diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.output/output_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.output/output_iterator.compile.pass.cpp --- a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.output/output_iterator.compile.pass.cpp +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.output/output_iterator.compile.pass.cpp @@ -28,6 +28,15 @@ static_assert( std::output_iterator, DerivedFromT>); static_assert(!std::output_iterator, T>); +static_assert( std::output_iterator, int>); +static_assert( std::output_iterator, short>); +static_assert( std::output_iterator, long>); +static_assert( std::output_iterator, T>); +static_assert(!std::output_iterator, T>); +static_assert( std::output_iterator, T const>); +static_assert( std::output_iterator, DerivedFromT>); +static_assert(!std::output_iterator, T>); + // Not satisfied when the iterator is not an input_or_output_iterator static_assert(!std::output_iterator); static_assert(!std::output_iterator); 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 @@ -514,6 +514,43 @@ struct iter_value_or_void { using type = std::iter_value_t; }; +#endif // TEST_STD_VER > 17 + +// This iterator will be used in tests using older language standards. +template +class cpp20_output_iterator +{ + It it_; +public: +#if TEST_STD_VER > 17 + using difference_type = std::iter_difference_t; +#else + using difference_type = typename std::iterator_traits::difference_type; +#endif + + TEST_CONSTEXPR explicit cpp20_output_iterator(It it) : it_(it) {} + cpp20_output_iterator(cpp20_output_iterator&&) = default; + cpp20_output_iterator& operator=(cpp20_output_iterator&&) = default; +#if TEST_STD_VER > 17 + constexpr decltype(auto) operator*() const { return *it_; } +#else + typename std::iterator_traits::reference operator*() const { return *it_; } +#endif + TEST_CONSTEXPR_CXX14 cpp20_output_iterator& operator++() { ++it_; return *this; } + TEST_CONSTEXPR_CXX14 cpp20_output_iterator operator++(int) { + auto temp = *this; + ++*this; + return temp; + } + + friend TEST_CONSTEXPR It base(const cpp20_output_iterator& i) { return i.it_; } + + template + void operator,(T const &) = delete; +}; + +#if TEST_STD_VER > 17 +static_assert(std::output_iterator, int>); // Iterator adaptor that counts the number of times the iterator has had a successor/predecessor // operation called. Has two recorders: