Index: libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp +++ libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp @@ -46,17 +46,23 @@ struct BadReturnType { BadReturnType empty() { return {}; } }; -static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); struct BoolConvertible { - constexpr operator bool() noexcept(false) { return true; } + constexpr /*TODO: explicit*/ operator bool() noexcept(false) { return true; } }; struct BoolConvertibleReturnType { constexpr BoolConvertible empty() noexcept { return {}; } }; - static_assert(!noexcept(std::ranges::empty(BoolConvertibleReturnType()))); +struct InputIterators { + cpp17_input_iterator begin() const; + cpp17_input_iterator end() const; +}; +static_assert(std::is_same_v); +static_assert(!std::is_invocable_v); + constexpr bool testEmptyMember() { HasMemberAndFunction a; assert(std::ranges::empty(a) == true); @@ -77,6 +83,13 @@ friend constexpr size_t size(SizeFunction sf) { return sf.size_; } }; +struct BeginEndSizedSentinel { + constexpr int *begin() const { return nullptr; } + constexpr auto end() const { return sized_sentinel(nullptr); } +}; +static_assert(std::ranges::forward_range); +static_assert(std::ranges::sized_range); + constexpr bool testUsingRangesSize() { SizeMember a{1}; assert(std::ranges::empty(a) == false); @@ -88,82 +101,46 @@ SizeFunction d{0}; assert(std::ranges::empty(d) == true); + BeginEndSizedSentinel e; + assert(std::ranges::empty(e) == true); + return true; } -struct other_forward_iterator : forward_iterator { }; - -struct sentinel { - constexpr bool operator==(std::input_or_output_iterator auto) const { return true; } -}; - struct BeginEndNotSizedSentinel { - friend constexpr forward_iterator begin(BeginEndNotSizedSentinel) { return {}; } - friend constexpr sentinel end(BeginEndNotSizedSentinel) { return {}; } + constexpr int *begin() const { return nullptr; } + constexpr auto end() const { return sentinel_wrapper(nullptr); } }; -static_assert(!std::is_invocable_v); - -struct InvalidMinusBeginEnd { - friend constexpr random_access_iterator begin(InvalidMinusBeginEnd) { return {}; } - friend constexpr sentinel end(InvalidMinusBeginEnd) { return {}; } -}; - -// Int is integer-like, but it is not other_forward_iterator's difference_type. -constexpr short operator-(sentinel, random_access_iterator) { return 2; } -constexpr short operator-(random_access_iterator, sentinel) { return 2; } -static_assert(!std::is_invocable_v); +static_assert( std::ranges::forward_range); +static_assert(!std::ranges::sized_range); -// This type will use ranges::size. -struct IntPtrBeginAndEnd { - int buff[8]; - constexpr int* begin() { return buff; } - constexpr int* end() { return buff + 8; } -}; -static_assert(std::is_invocable_v); - -// size is disabled here, and it isn't sized_sentinel_for, so we have to compare begin -// and end again. +// size is disabled here, so we have to compare begin and end. struct DisabledSizeRangeWithBeginEnd { - friend constexpr forward_iterator begin(DisabledSizeRangeWithBeginEnd) { return {}; } - friend constexpr sentinel end(DisabledSizeRangeWithBeginEnd) { return {}; } - constexpr size_t size() const { return 1; } + constexpr int *begin() const { return nullptr; } + constexpr auto end() const { return sentinel_wrapper(nullptr); } + size_t size() const; }; - -template <> +template<> inline constexpr bool std::ranges::disable_sized_range = true; -static_assert(!std::is_invocable_v); +static_assert(std::ranges::contiguous_range); +static_assert(!std::ranges::sized_range); struct BeginEndAndEmpty { - int* begin(); - int* end(); - constexpr bool empty() { return true; } -}; - -struct BeginEndAndConstEmpty { - int* begin(); - int* end(); - constexpr bool empty() const { return true; } + constexpr int *begin() const { return nullptr; } + constexpr auto end() const { return sentinel_wrapper(nullptr); } + constexpr bool empty() { return false; } }; constexpr bool testBeginEqualsEnd() { BeginEndNotSizedSentinel a; assert(std::ranges::empty(a) == true); - InvalidMinusBeginEnd b; - assert(std::ranges::empty(b) == true); - - IntPtrBeginAndEnd c; - assert(std::ranges::empty(c) == false); - DisabledSizeRangeWithBeginEnd d; assert(std::ranges::empty(d) == true); BeginEndAndEmpty e; - assert(std::ranges::empty(e) == true); - - BeginEndAndConstEmpty f; - assert(std::ranges::empty(f) == true); - assert(std::ranges::empty(std::as_const(f)) == true); + assert(std::ranges::empty(e) == false); // e.empty() + assert(std::ranges::empty(std::as_const(e)) == true); // e.begin() == e.end() return true; } Index: libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp =================================================================== --- libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp +++ libcxx/test/std/ranges/range.access/range.prim/ssize.pass.cpp @@ -30,8 +30,7 @@ struct SizeMember { constexpr size_t size() { return 42; } }; - -static_assert(!std::is_invocable_v); +static_assert(!std::is_invocable_v); struct SizeFunction { friend constexpr size_t size(SizeFunction) { return 42; } @@ -41,18 +40,12 @@ friend constexpr std::ptrdiff_t size(SizeFunctionSigned) { return 42; } }; -struct sentinel { - bool operator==(std::input_or_output_iterator auto) const { return true; } -}; - -struct RandomAccesslRange { - constexpr random_access_iterator begin() { return {}; } - constexpr sentinel end() { return {}; } +struct SizedSentinelRange { + int data_[2] = {}; + constexpr int *begin() { return data_; } + constexpr auto end() { return sized_sentinel(data_ + 2); } }; -constexpr std::ptrdiff_t operator-(const sentinel, const random_access_iterator) { return 2; } -constexpr std::ptrdiff_t operator-(const random_access_iterator, const sentinel) { return 2; } - struct ShortUnsignedReturnType { constexpr unsigned short size() { return 42; } }; @@ -75,7 +68,7 @@ assert(std::ranges::ssize(SizeFunctionSigned()) == 42); ASSERT_SAME_TYPE(decltype(std::ranges::ssize(SizeFunctionSigned())), std::ptrdiff_t); - RandomAccesslRange b; + SizedSentinelRange b; assert(std::ranges::ssize(b) == 2); ASSERT_SAME_TYPE(decltype(std::ranges::ssize(b)), std::ptrdiff_t); Index: libcxx/test/support/test_iterators.h =================================================================== --- libcxx/test/support/test_iterators.h +++ libcxx/test/support/test_iterators.h @@ -42,6 +42,8 @@ TEST_CONSTEXPR_CXX14 output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;} + friend TEST_CONSTEXPR It base(const output_iterator& i) { return i.it_; } + template void operator,(T const &) = delete; }; @@ -81,6 +83,8 @@ friend TEST_CONSTEXPR_CXX14 bool operator!=(const cpp17_input_iterator& x, const cpp17_input_iterator& y) {return !(x == y);} + friend TEST_CONSTEXPR It base(const cpp17_input_iterator& i) { return i.it_; } + template void operator,(T const &) = delete; }; @@ -129,6 +133,8 @@ friend TEST_CONSTEXPR_CXX14 bool operator!=(const forward_iterator& x, const forward_iterator& y) {return !(x == y);} + friend TEST_CONSTEXPR It base(const forward_iterator& i) { return i.it_; } + template void operator,(T const &) = delete; }; @@ -229,6 +235,8 @@ TEST_CONSTEXPR_CXX14 bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;} + friend TEST_CONSTEXPR It base(const bidirectional_iterator& i) { return i.it_; } + template void operator,(T const &) = delete; }; @@ -289,6 +297,8 @@ TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];} + friend TEST_CONSTEXPR It base(const random_access_iterator& i) { return i.it_; } + template void operator,(T const &) = delete; }; @@ -419,32 +429,14 @@ return x.base() != y.base(); } + friend TEST_CONSTEXPR It base(const contiguous_iterator& i) { return i.it_; } + template void operator,(T const &) = delete; }; #endif -template -TEST_CONSTEXPR_CXX14 Iter base(output_iterator i) { return i.base(); } - -template -TEST_CONSTEXPR_CXX14 Iter base(cpp17_input_iterator i) { return i.base(); } - -template -TEST_CONSTEXPR_CXX14 Iter base(forward_iterator i) { return i.base(); } - -template -TEST_CONSTEXPR_CXX14 Iter base(bidirectional_iterator i) { return i.base(); } - -template -TEST_CONSTEXPR_CXX14 Iter base(random_access_iterator i) { return i.base(); } - -#if TEST_STD_VER > 17 -template -TEST_CONSTEXPR_CXX14 Iter base(contiguous_iterator i) { return i.base(); } -#endif - -template // everything else +template // ADL base() for everything else (including pointers) TEST_CONSTEXPR_CXX14 Iter base(Iter i) { return i; } template @@ -628,42 +620,30 @@ #ifdef TEST_SUPPORTS_RANGES -template -struct cpp20_input_iterator { - using value_type = std::iter_value_t; - using difference_type = std::iter_difference_t; - using iterator_concept = std::input_iterator_tag; +template +class cpp20_input_iterator +{ + It it_; - cpp20_input_iterator() = delete; +public: + using value_type = std::iter_value_t; + using difference_type = std::iter_difference_t; + using iterator_concept = std::input_iterator_tag; + constexpr explicit cpp20_input_iterator(It it) : it_(it) {} cpp20_input_iterator(cpp20_input_iterator&&) = default; cpp20_input_iterator& operator=(cpp20_input_iterator&&) = default; + constexpr decltype(auto) operator*() const { return *it_; } + constexpr cpp20_input_iterator& operator++() { ++it_; return *this; } + constexpr void operator++(int) { ++it_; } - cpp20_input_iterator(cpp20_input_iterator const&) = delete; - cpp20_input_iterator& operator=(cpp20_input_iterator const&) = delete; + constexpr const It& base() const& { return it_; } + constexpr It base() && { return std::move(it_); } - explicit constexpr cpp20_input_iterator(I base) : base_(std::move(base)) {} - - constexpr decltype(auto) operator*() const { return *base_; } - - constexpr cpp20_input_iterator& operator++() { - ++base_; - return *this; - } - - constexpr void operator++(int) { ++base_; } - - constexpr const I& base() const& { return base_; } - - constexpr I base() && { return std::move(base_); } - - friend constexpr I base(const cpp20_input_iterator& i) { return i.base_; } + friend constexpr It base(const cpp20_input_iterator& i) { return i.it_; } template void operator,(T const &) = delete; - -private: - I base_ = I(); }; template @@ -960,15 +940,15 @@ constexpr reference operator[](difference_type n) const {return it_[n];} - template - void operator,(T const &) = delete; - friend constexpr difference_type operator-(const three_way_contiguous_iterator& x, const three_way_contiguous_iterator& y) { return x.base() - y.base(); } friend auto operator<=>(const three_way_contiguous_iterator&, const three_way_contiguous_iterator&) = default; + + template + void operator,(T const &) = delete; }; #endif // TEST_STD_VER > 17 && defined(__cpp_lib_concepts)