Skip to content

Commit 44284cd

Browse files
committed
[libc++][ranges] LWG3610: iota_view::size sometimes rejects integer-class types
Fixes #104948 - https://wg21.link/LWG3610
1 parent ef98e24 commit 44284cd

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

libcxx/docs/Status/Cxx23Issues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
"`LWG3598 <https://wg21.link/LWG3598>`__","``system_category().default_error_condition(0)`` is underspecified","2022-02 (Virtual)","","",""
144144
"`LWG3601 <https://wg21.link/LWG3601>`__","common_iterator's postfix-proxy needs ``indirectly_readable`` ","2022-02 (Virtual)","","",""
145145
"`LWG3607 <https://wg21.link/LWG3607>`__","``contiguous_iterator`` should not be allowed to have custom ``iter_move`` and ``iter_swap`` behavior","2022-02 (Virtual)","|Nothing To Do|","",""
146-
"`LWG3610 <https://wg21.link/LWG3610>`__","``iota_view::size`` sometimes rejects integer-class types","2022-02 (Virtual)","","",""
146+
"`LWG3610 <https://wg21.link/LWG3610>`__","``iota_view::size`` sometimes rejects integer-class types","2022-02 (Virtual)","|Complete|","22",""
147147
"`LWG3612 <https://wg21.link/LWG3612>`__","Inconsistent pointer alignment in ``std::format`` ","2022-02 (Virtual)","|Complete|","14",""
148148
"`LWG3616 <https://wg21.link/LWG3616>`__","LWG 3498 seems to miss the non-member ``swap`` for ``basic_syncbuf`` ","2022-02 (Virtual)","|Complete|","18",""
149149
"`LWG3618 <https://wg21.link/LWG3618>`__","Unnecessary ``iter_move`` for ``transform_view::iterator`` ","2022-02 (Virtual)","|Complete|","19",""

libcxx/include/__ranges/iota_view.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
348348

349349
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
350350
requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
351-
(integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
351+
(__integer_like<_Start> && __integer_like<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
352352
{
353353
if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
354354
return (__value_ < 0)

libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,21 @@
1616
#include <ranges>
1717

1818
#include "test_macros.h"
19+
#define TEST_HAS_NO_INT128
20+
#include "type_algorithms.h"
1921
#include "types.h"
2022

23+
template <typename T>
24+
concept HasSize = requires(const T t) { t.size(); };
25+
26+
struct CheckForSize {
27+
template <class T>
28+
constexpr void operator()() {
29+
static_assert(HasSize<std::ranges::iota_view<T, int>>);
30+
static_assert(HasSize<std::ranges::iota_view<T, T>>);
31+
}
32+
};
33+
2134
constexpr bool test() {
2235
// Both are integer like and both are less than zero.
2336
{
@@ -99,6 +112,11 @@ constexpr bool test() {
99112
assert(sz == 10);
100113
}
101114

115+
// LWG3610: `iota_view::size` sometimes rejects integer-class types
116+
{
117+
types::for_each(types::integer_types{}, CheckForSize{});
118+
}
119+
102120
return true;
103121
}
104122

0 commit comments

Comments
 (0)