diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h --- a/libcxx/test/support/test_iterators.h +++ b/libcxx/test/support/test_iterators.h @@ -634,14 +634,12 @@ bool operator!= (const NonThrowingIterator& a, const NonThrowingIterator& b) TEST_NOEXCEPT { return !a.operator==(b); } -#ifdef TEST_SUPPORTS_RANGES - -// clang-format off +#if TEST_STD_VER >= 14 template struct cpp20_input_iterator { - using value_type = std::iter_value_t; - using difference_type = std::iter_difference_t; + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; using iterator_concept = std::input_iterator_tag; cpp20_input_iterator() = default; @@ -655,22 +653,39 @@ 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_; } - [[nodiscard]] constexpr I const& base() const& { return base_; } + constexpr I const& base() const& { return base_; } + constexpr I base() && { return std::move(base_); } - [[nodiscard]] constexpr I base() && { return std::move(base_); } + struct sentinel { + friend cpp20_input_iterator; + + sentinel() = default; + sentinel(I base) : base(base) {} + + private: + I base = I(); + }; + + friend constexpr bool operator==(const sentinel& lhs, const cpp20_input_iterator& rhs) { return lhs.base == rhs.base(); } + friend constexpr bool operator==(const cpp20_input_iterator& lhs, const sentinel& rhs) { return lhs.base() == rhs.base; } + + template + void operator,(T const &) DELETE_FUNCTION; private: I base_ = I(); }; +#endif // TEST_STD_VER >= 14 + +#ifdef TEST_SUPPORTS_RANGES + template struct iterator_concept { using type = std::output_iterator_tag; @@ -854,6 +869,9 @@ return !(x < y); } + template + void operator,(T const &) DELETE_FUNCTION; + private: I base_; difference_type stride_count_ = 0;