struct I { using value_type = int; using difference_type = int; int operator*() const; I& operator++(); I operator++(int); I& operator--(); I operator--(int); bool operator==(I) const; bool operator!=(I) const; };iterator_traits<I>::iterator_category denotes input_iterator_tag, and ITER_CONCEPT(I) denotes random_access_iterator_tag.
template<class In> concept Readable = requires { typename iter_value_t<In>; typename iter_reference_t<In>; typename iter_rvalue_reference_t<In>; } && CommonReference<iter_reference_t<In>&&, iter_value_t<In>&> && CommonReference<iter_reference_t<In>&&, iter_rvalue_reference_t<In>&&> && CommonReference<iter_rvalue_reference_t<In>&&, const iter_value_t<In>&>;
template<class Out, class T> concept Writable = requires(Out&& o, T&& t) { *o = std::forward<T>(t); // not required to be equality-preserving *std::forward<Out>(o) = std::forward<T>(t); // not required to be equality-preserving const_cast<const iter_reference_t<Out>&&>(*o) = std::forward<T>(t); // not required to be equality-preserving const_cast<const iter_reference_t<Out>&&>(*std::forward<Out>(o)) = std::forward<T>(t); // not required to be equality-preserving };
template<class I> concept WeaklyIncrementable = Semiregular<I> && requires(I i) { typename iter_difference_t<I>; requires SignedIntegral<iter_difference_t<I>>; { ++i } -> Same<I&>; // not required to be equality-preserving i++; // not required to be equality-preserving };
template<class I> concept Incrementable = Regular<I> && WeaklyIncrementable<I> && requires(I i) { { i++ } -> Same<I>; };
template<class I> concept Iterator = requires(I i) { { *i } -> can-reference; } && WeaklyIncrementable<I>;
template<class S, class I>
concept Sentinel =
Semiregular<S> &&
Iterator<I> &&
weakly-equality-comparable-with<S, I>; // See [concept.equalitycomparable]
template<class S, class I>
concept SizedSentinel =
Sentinel<S, I> &&
!disable_sized_sentinel<remove_cv_t<S>, remove_cv_t<I>> &&
requires(const I& i, const S& s) {
{ s - i } -> Same<iter_difference_t<I>>;
{ i - s } -> Same<iter_difference_t<I>>;
};
template<class I> concept InputIterator = Iterator<I> && Readable<I> && requires { typename ITER_CONCEPT(I); } && DerivedFrom<ITER_CONCEPT(I), input_iterator_tag>;
template<class I, class T> concept OutputIterator = Iterator<I> && Writable<I, T> && requires(I i, T&& t) { *i++ = std::forward<T>(t); // not required to be equality-preserving };
*i = E; ++i;
template<class I> concept ForwardIterator = InputIterator<I> && DerivedFrom<ITER_CONCEPT(I), forward_iterator_tag> && Incrementable<I> && Sentinel<I, I>;
template<class I> concept BidirectionalIterator = ForwardIterator<I> && DerivedFrom<ITER_CONCEPT(I), bidirectional_iterator_tag> && requires(I i) { { --i } -> Same<I&>; { i-- } -> Same<I>; };
template<class I> concept RandomAccessIterator = BidirectionalIterator<I> && DerivedFrom<ITER_CONCEPT(I), random_access_iterator_tag> && StrictTotallyOrdered<I> && SizedSentinel<I, I> && requires(I i, const I j, const iter_difference_t<I> n) { { i += n } -> Same<I&>; { j + n } -> Same<I>; { n + j } -> Same<I>; { i -= n } -> Same<I&>; { j - n } -> Same<I>; { j[n] } -> Same<iter_reference_t<I>>; };
template<class I> concept ContiguousIterator = RandomAccessIterator<I> && DerivedFrom<ITER_CONCEPT(I), contiguous_iterator_tag> && is_lvalue_reference_v<iter_reference_t<I>> && Same<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>>;