diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv index d1546f4a452b5..d54cd135ff94e 100644 --- a/libcxx/docs/Status/Cxx23Issues.csv +++ b/libcxx/docs/Status/Cxx23Issues.csv @@ -143,7 +143,7 @@ "`LWG3598 `__","``system_category().default_error_condition(0)`` is underspecified","2022-02 (Virtual)","","","" "`LWG3601 `__","common_iterator's postfix-proxy needs ``indirectly_readable`` ","2022-02 (Virtual)","","","" "`LWG3607 `__","``contiguous_iterator`` should not be allowed to have custom ``iter_move`` and ``iter_swap`` behavior","2022-02 (Virtual)","|Nothing To Do|","","" -"`LWG3610 `__","``iota_view::size`` sometimes rejects integer-class types","2022-02 (Virtual)","","","" +"`LWG3610 `__","``iota_view::size`` sometimes rejects integer-class types","2022-02 (Virtual)","|Complete|","22","" "`LWG3612 `__","Inconsistent pointer alignment in ``std::format`` ","2022-02 (Virtual)","|Complete|","14","" "`LWG3616 `__","LWG 3498 seems to miss the non-member ``swap`` for ``basic_syncbuf`` ","2022-02 (Virtual)","|Complete|","18","" "`LWG3618 `__","Unnecessary ``iter_move`` for ``transform_view::iterator`` ","2022-02 (Virtual)","|Complete|","19","" diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h index 32ff3408e54ea..d3d571e7efa4a 100644 --- a/libcxx/include/__ranges/iota_view.h +++ b/libcxx/include/__ranges/iota_view.h @@ -58,11 +58,17 @@ struct __get_wider_signed { return type_identity{}; else if constexpr (sizeof(_Int) < sizeof(long)) return type_identity{}; + else if constexpr (sizeof(_Int) < sizeof(long long)) + return type_identity{}; else +# if _LIBCPP_HAS_INT128 + return type_identity<__int128_t>{}; +# else return type_identity{}; static_assert( sizeof(_Int) <= sizeof(long long), "Found integer-like type that is bigger than largest integer like type."); +# endif } using type = typename decltype(__call())::type; @@ -349,7 +355,7 @@ class iota_view : public view_interface> { _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) || - (integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start> + (__integer_like<_Start> && __integer_like<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start> { if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) { return (__value_ < 0) diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/begin.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/begin.pass.cpp index 06419c1b14ee0..dbe052ea18287 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/begin.pass.cpp @@ -40,6 +40,10 @@ constexpr void testType() { constexpr bool test() { testType(); +#ifndef TEST_HAS_NO_INT128 + testType<__int128_t>(); + testType<__uint128_t>(); +#endif testType(); testType(); testType(); diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/end.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/end.pass.cpp index 6abbef55b6ba7..d12079fdb5eec 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/end.pass.cpp @@ -61,6 +61,14 @@ constexpr void testType(U u) { constexpr bool test() { testType(SomeInt(10)); testType(IntComparableWith(SomeInt(10))); +#ifndef TEST_HAS_NO_INT128 + testType<__int128_t>(__int128_t(10)); + testType<__uint128_t>(__uint128_t(10)); +#endif + testType(10LL); + testType(10ULL); + testType(IntComparableWith(10)); + testType(IntComparableWith(10)); testType(IntComparableWith(10)); testType(IntComparableWith(10)); testType(IntComparableWith(10)); diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp index c2f7fd14042a8..2cd7105adad4b 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp @@ -106,7 +106,11 @@ void test() { // Same as below, if there is no type larger than long, we can just use that. static_assert(sizeof(Iter::difference_type) >= sizeof(long)); static_assert(std::is_signed_v); +#ifdef TEST_HAS_NO_INT128 LIBCPP_STATIC_ASSERT(std::same_as); +#else + LIBCPP_STATIC_ASSERT(std::same_as); +#endif } { const std::ranges::iota_view io(0); @@ -118,7 +122,11 @@ void test() { // https://eel.is/c++draft/range.iota.view#1.3 static_assert(sizeof(Iter::difference_type) >= sizeof(long long)); static_assert(std::is_signed_v); +#ifdef TEST_HAS_NO_INT128 LIBCPP_STATIC_ASSERT(std::same_as); +#else + LIBCPP_STATIC_ASSERT(std::same_as); +#endif } { const std::ranges::iota_view io; diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp index 570c74e29c686..b776d90c5e5e3 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp @@ -81,6 +81,12 @@ constexpr void testType() { constexpr bool test() { testType(); testType(); +#ifndef TEST_HAS_NO_INT128 + testType<__int128_t>(); + testType<__uint128_t>(); +#endif + testType(); + testType(); testType(); testType(); testType(); diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/subscript.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/subscript.pass.cpp index 0e5aca0dd554c..786b63dfeedee 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/subscript.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/subscript.pass.cpp @@ -47,6 +47,12 @@ constexpr void testType() { constexpr bool test() { testType(); +#ifndef TEST_HAS_NO_INT128 + testType<__int128_t>(); + testType<__uint128_t>(); +#endif + testType(); + testType(); testType(); testType(); testType(); diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp index b894bc542be10..bb8215339b2bd 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp @@ -16,8 +16,21 @@ #include #include "test_macros.h" +#include "type_algorithms.h" #include "types.h" +template +concept HasSize = requires(const T t) { t.size(); }; + +struct CheckForSize { + template + constexpr void operator()() { + types::for_each(types::integer_types{}, []() { + static_assert(HasSize>); + }); + } +}; + constexpr bool test() { // Both are integer like and both are less than zero. { @@ -99,6 +112,11 @@ constexpr bool test() { assert(sz == 10); } + // LWG3610: `iota_view::size` sometimes rejects integer-class types + { + types::for_each(types::integer_types{}, CheckForSize{}); + } + return true; }