Namespaces
Variants
Views
Actions

Standard library header <iterator>

From cppreference.com
< cpp‎ | header
 
 
 

This header is part of the iterator library.

Contents

Concepts

Iterator concepts
specifies that a type is readable by applying operator *
(concept) [edit]
specifies that a value can be written to an iterator's referenced object
(concept) [edit]
specifies that a Semiregular type can be incremented with pre- and post-increment operators
(concept) [edit]
specifies that the increment operation on a WeaklyIncrementable type is equality-preserving and that the type is EqualityComparable
(concept) [edit]
specifies that objects of a type can be incremented and dereferenced
(concept) [edit]
specifies a type is a sentinel for an Iterator type
(concept) [edit]
specifies that the - operator can be applied to an iterator and a sentinel to calculate their difference in constant time
(concept) [edit]
specifies that a type is an input iterator, that is, its referenced values can be read and it can be both pre- and post-incremented
(concept) [edit]
specifies that a type is an output iterator for a given value type, that is, values of that type can be written to it and it can be both pre- and post-incremented
(concept) [edit]
specifies that an InputIterator is a forward iterator, supporting equality comparison and multi-pass
(concept) [edit]
specifies that a ForwardIterator is a bidirectional interator, supporting movement backwards
(concept) [edit]
specifies that a BidirectionalIterator is a random-access iterator, supporting advancement in constant time and subscripting
(concept) [edit]
specifies that a RandomAccessIterator is a contiguous iterator, referring to elements that are contiguous in memory
(concept) [edit]
Indirect callable concepts
specifies that a callable type can be invoked with the result of dereferencing a Readable type
(concept) [edit]
specifies that a callable type, when invoked with the result of dereferencing a Readable type, satisfies Predicate
(concept) [edit]
specifies that a callable type, when invoked with the result of dereferencing two Readable types, satisfies Predicate
(concept) [edit]
specifies that a callable type, when invoked with the result of dereferencing two Readable types, satisfies StrictWeakOrder
(concept) [edit]
Common algorithm requirements
specifies that values may be moved from a Readable type to a Writable type
(concept) [edit]
specifies that values may be moved from a Readable type to a Writable type and that the move may be performed via an intermediate object
(concept) [edit]
specifies that values may be copied from a Readable type to a Writable type
(concept) [edit]
specifies that values may be copied from a Readable type to a Writable type and that the copy may be performed via an intermediate object
(concept) [edit]
specifies that the values referenced by two Readable types can be swapped
(concept) [edit]
specifies that the values referenced by two Readable types can be compared
(concept) [edit]
specifies the common requirements of algorithms that reorder elements in place
(concept) [edit]
specifies the requirements of algorithms that merge sorted sequences into an output sequence by copying elements
(concept) [edit]
specifies the common requirements of algorithms that permute sequences into ordered sequences
(concept) [edit]

Classes

Algorithm utilities
computes the result of invoking a callable object on the result of dereferencing some set of Readable types
(alias template) [edit]
helper template for specifying the constraints on algorithms that accept projections
(class template) [edit]
Associated types
computes the difference type of a WeaklyIncrementable type
(class template) [edit]
computes the value type of a Readable type
(class template) [edit]
computes the associate types of an iterator
(alias template) [edit]
Primitives
provides uniform interface to the properties of an iterator
(class template) [edit]
empty class types used to indicate iterator categories
(class) [edit]
(deprecated in C++17)
base class to ease the definition of required types for simple iterators
(class template) [edit]
Adaptors
iterator adaptor for reverse-order traversal
(class template) [edit]
iterator adaptor which dereferences to an rvalue reference
(class template) [edit]
sentinel adaptor for use with std::move_iterator
(class template) [edit]
adapts an iterator type and its sentinel into a common iterator type
(class template) [edit]
default sentinel for use with iterators that know the bound of their range
(class) [edit]
iterator adaptor that tracks the distance to the end of the range
(class template) [edit]
sentinel that always compares unequal to any WeaklyIncrementable type
(class) [edit]
iterator adaptor for insertion at the end of a container
(class template) [edit]
iterator adaptor for insertion at the front of a container
(class template) [edit]
iterator adaptor for insertion into a container
(class template) [edit]
Stream Iterators
input iterator that reads from std::basic_istream
(class template) [edit]
output iterator that writes to std::basic_ostream
(class template) [edit]
input iterator that reads from std::basic_streambuf
(class template) [edit]
output iterator that writes to std::basic_streambuf
(class template) [edit]

Customization point objects

Defined in namespace std::ranges
casts the result of dereferencing an object to its associated rvalue reference type
(customization point object) [edit]
swap the values referenced by two dereferenceable objects
(customization point object) [edit]

Functions

Adaptors
creates a std::reverse_iterator of type inferred from the argument
(function template) [edit]
creates a std::move_iterator of type inferred from the argument
(function template) [edit]
creates a std::front_insert_iterator of type inferred from the argument
(function template) [edit]
creates a std::back_insert_iterator of type inferred from the argument
(function template) [edit]
creates a std::insert_iterator of type inferred from the argument
(function template) [edit]
Non-member operators
compares the underlying iterators
(function template) [edit]
advances the iterator
(function template) [edit]
computes the distance between two iterator adaptors
(function template) [edit]
compares the underlying iterators
(function template) [edit]
advances the iterator
(function template) [edit]
computes the distance between two iterator adaptors
(function template) [edit]
compares two istream_iterators
(function template) [edit]
compares two istreambuf_iterators
(function template) [edit]
Operations
advances an iterator by given distance
(function template) [edit]
returns the distance between two iterators
(function template) [edit]
(C++11)
increment an iterator
(function template) [edit]
(C++11)
decrement an iterator
(function template) [edit]
advances an iterator by given distance or to a given bound
(niebloid) [edit]
returns the distance between an iterator and a sentinel, or between the beginning and end of a range
(niebloid) [edit]
increment an iterator by a given distance or to a bound
(niebloid) [edit]
decrement an iterator by a given distance or to a bound
(niebloid) [edit]
Range access
(C++11)(C++14)
returns an iterator to the beginning of a container or array
(function template) [edit]
(C++11)(C++14)
returns an iterator to the end of a container or array
(function template) [edit]
returns a reverse iterator to a container or array
(function template) [edit]
(C++14)
returns a reverse end iterator for a container or array
(function template) [edit]
(C++17)(C++20)
returns the size of a container or array
(function template) [edit]
(C++17)
checks whether the container is empty
(function template) [edit]
(C++17)
obtains the pointer to the underlying array
(function template) [edit]

[edit] Synopsis

#include <concepts>
 
namespace std {
  template<class T> using __with_reference = T&;// exposition only
  template<class T> concept __Referenceable     // exposition only
    = requires { typename __with_reference<T>; };
  template<class T> concept __Dereferenceable   // exposition only
    = requires(T& t) {
      { *t } -> __Referenceable; // not required to be equality-preserving
    };
 
  // associated types
  // incrementable traits
  template<class> struct incrementable_traits;
  template<class T>
    using iter_difference_t = /* see definition */;
 
  // readable traits
  template<class> struct readable_traits;
  template<class T>
    using iter_value_t = /* see definition */;
 
  // iterator traits
  template<class I> struct iterator_traits;
  template<class T> struct iterator_traits<T*>;
 
  template<__Dereferenceable T>
    using iter_reference_t = decltype(*declval<T&>());
 
  namespace ranges {
    // customization points
    inline namespace /* unspecified */ {
      // ranges​::​iter_­move
      inline constexpr /* unspecified */ iter_move = /* unspecified */;
 
      // ranges​::​iter_­swap
      inline constexpr /* unspecified */ iter_swap = /* unspecified */;
    }
  }
 
  template<__Dereferenceable T>
    requires requires(T& t) {
      { ranges::iter_move(t) } -> __Referenceable;
    }
  using iter_rvalue_reference_t
    = decltype(ranges::iter_move(declval<T&>()));
 
  // iterator concepts
  // concept Readable
  template<class In>
    concept Readable = /* see definition */;
 
  template<Readable T>
    using iter_common_reference_t =
      common_reference_t<iter_reference_t<T>, iter_value_t<T>&>;
 
  // concept Writable
  template<class Out, class T>
    concept Writable = /* see definition */;
 
  // concept WeaklyIncrementable
  template<class I>
    concept WeaklyIncrementable = /* see definition */;
 
  // concept Incrementable
  template<class I>
    concept Incrementable = /* see definition */;
 
  // concept Iterator
  template<class I>
    concept Iterator = /* see definition */;
 
  // concept Sentinel
  template<class S, class I>
    concept Sentinel = /* see definition */;
 
  // concept SizedSentinel
  template<class S, class I>
    inline constexpr bool disable_sized_sentinel = false;
 
  template<class S, class I>
    concept SizedSentinel = /* see definition */;
 
  // concept InputIterator
  template<class I>
    concept InputIterator = /* see definition */;
 
  // concept OutputIterator
  template<class I, class T>
    concept OutputIterator = /* see definition */;
 
  // concept ForwardIterator
  template<class I>
    concept ForwardIterator = /* see definition */;
 
  // concept BidirectionalIterator
  template<class I>
    concept BidirectionalIterator = /* see definition */;
 
  // concept RandomAccessIterator
  template<class I>
    concept RandomAccessIterator = /* see definition */;
 
  // concept ContiguousIterator
  template<class I>
    concept ContiguousIterator = /* see definition */;
 
  // indirect callable requirements
  // indirect callables
  template<class F, class I>
    concept IndirectUnaryInvocable = /* see definition */;
 
  template<class F, class I>
    concept IndirectRegularUnaryInvocable = /* see definition */;
 
  template<class F, class I>
    concept IndirectUnaryPredicate = /* see definition */;
 
  template<class F, class I1, class I2 = I1>
    concept IndirectRelation = /* see definition */;
 
  template<class F, class I1, class I2 = I1>
    concept IndirectStrictWeakOrder = /* see definition */;
 
  template<class F, class... Is>
    requires (Readable<Is> && ...) && Invocable<F, iter_reference_t<Is>...>
      using indirect_result_t = invoke_result_t<F, iter_reference_t<Is>...>;
 
  // projected
  template<Readable I, IndirectRegularUnaryInvocable<I> Proj>
    struct projected;
 
  template<WeaklyIncrementable I, class Proj>
    struct incrementable_traits<projected<I, Proj>>;
 
  // common algorithm requirements
  // concept IndirectlyMovable
  template<class In, class Out>
    concept IndirectlyMovable = /* see definition */;
 
  template<class In, class Out>
    concept IndirectlyMovableStorable = /* see definition */;
 
  // concept IndirectlyCopyable
  template<class In, class Out>
    concept IndirectlyCopyable = /* see definition */;
 
  template<class In, class Out>
    concept IndirectlyCopyableStorable = /* see definition */;
 
  // concept IndirectlySwappable
  template<class I1, class I2 = I1>
    concept IndirectlySwappable = /* see definition */;
 
  // concept IndirectlyComparable
  template<class I1, class I2, class R, class P1 = identity, class P2 = identity>
    concept IndirectlyComparable = /* see definition */;
 
  // concept Permutable
  template<class I>
    concept Permutable = /* see definition */;
 
  // concept Mergeable
  template<class I1, class I2, class Out,
      class R = ranges::less, class P1 = identity, class P2 = identity>
    concept Mergeable = /* see definition */;
 
  // concept Sortable
  template<class I, class R = ranges::less, class P = identity>
    concept Sortable = /* see definition */;
 
  // primitives
  // iterator tags
  struct input_iterator_tag { };
  struct output_iterator_tag { };
  struct forward_iterator_tag: public input_iterator_tag { };
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };
  struct contiguous_iterator_tag: public random_access_iterator_tag { };
 
  // iterator operations
  template<class InputIter, class Distance>
    constexpr void
      advance(InputIter& i, Distance n);
  template<class InputIter>
    constexpr typename iterator_traits<InputIter>::difference_type
      distance(InputIter first, InputIter last);
  template<class InputIter>
    constexpr InputIter
      next(InputIter x,
           typename iterator_traits<InputIter>::difference_type n = 1);
  template<class BidirIter>
    constexpr BidirIter
      prev(BidirIter x,
           typename iterator_traits<BidirIter>::difference_type n = 1);
 
  // range iterator operations
  namespace ranges {
    // ranges​::​advance
    template<Iterator I>
      constexpr void advance(I& i, iter_difference_t<I> n);
    template<Iterator I, Sentinel<I> S>
      constexpr void advance(I& i, S bound);
    template<Iterator I, Sentinel<I> S>
      constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound);
 
    // ranges​::​distance
    template<Iterator I, Sentinel<I> S>
      constexpr iter_difference_t<I> distance(I first, S last);
    template<Range R>
      constexpr iter_difference_t<iterator_t<R>> distance(R&& r);
 
    // ranges​::​next
    template<Iterator I>
      constexpr I next(I x);
    template<Iterator I>
      constexpr I next(I x, iter_difference_t<I> n);
    template<Iterator I, Sentinel<I> S>
      constexpr I next(I x, S bound);
    template<Iterator I, Sentinel<I> S>
      constexpr I next(I x, iter_difference_t<I> n, S bound);
 
    // ranges​::​prev
    template<BidirectionalIterator I>
      constexpr I prev(I x);
    template<BidirectionalIterator I>
      constexpr I prev(I x, iter_difference_t<I> n);
    template<BidirectionalIterator I>
      constexpr I prev(I x, iter_difference_t<I> n, I bound);
  }
 
  // predefined iterators and sentinels
  // reverse iterators
  template<class Iter> class reverse_iterator;
 
  template<class Iter1, class Iter2>
    constexpr bool operator==(
      const reverse_iterator<Iter1>& x,
      const reverse_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator!=(
      const reverse_iterator<Iter1>& x,
      const reverse_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator<(
      const reverse_iterator<Iter1>& x,
      const reverse_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator>(
      const reverse_iterator<Iter1>& x,
      const reverse_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator<=(
      const reverse_iterator<Iter1>& x,
      const reverse_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator>=(
      const reverse_iterator<Iter1>& x,
      const reverse_iterator<Iter2>& y);
 
  template<class Iter1, class Iter2>
    constexpr auto operator-(
      const reverse_iterator<Iter1>& x,
      const reverse_iterator<Iter2>& y) -> decltype(y.base() - x.base());
  template<class Iter>
    constexpr reverse_iterator<Iter>
      operator+(
    typename reverse_iterator<Iter>::difference_type n,
    const reverse_iterator<Iter>& x);
 
  template<class Iter>
    constexpr reverse_iterator<Iter> make_reverse_iterator(Iter i);
 
  template<class Iter1, class Iter2>
      requires (!SizedSentinel<Iter1, Iter2>)
    inline constexpr bool disable_sized_sentinel<reverse_iterator<Iter1>,
                                                 reverse_iterator<Iter2>> = true;
 
  // insert iterators
  template<class Container> class back_insert_iterator;
  template<class Container>
    constexpr back_insert_iterator<Container> back_inserter(Container& x);
 
  template<class Container> class front_insert_iterator;
  template<class Container>
    constexpr front_insert_iterator<Container> front_inserter(Container& x);
 
  template<class Container> class insert_iterator;
  template<class Container>
    constexpr insert_iterator<Container>
      inserter(Container& x, ranges::iterator_t<Container> i);
 
  // move iterators and sentinels
  template<class Iter> class move_iterator;
 
  template<class Iter1, class Iter2>
    constexpr bool operator==(
      const move_iterator<Iter1>& x, const move_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator!=(
      const move_iterator<Iter1>& x, const move_iterator<Iter2>& y);
  template<class Iterator1, class Iterator2>
    constexpr bool operator<(
      const move_iterator<Iter1>& x, const move_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator>(
      const move_iterator<Iter1>& x, const move_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator<=(
      const move_iterator<Iter1>& x, const move_iterator<Iter2>& y);
  template<class Iter1, class Iter2>
    constexpr bool operator>=(
      const move_iterator<Iter1>& x, const move_iterator<Iter2>& y);
 
  template<class Iter1, class Iter2>
    constexpr auto operator-(
    const move_iterator<Iter1>& x,
    const move_iterator<Iter2>& y) -> decltype(x.base() - y.base());
  template<class Iter>
    constexpr move_iterator<Iter> operator+(
      typename move_iterator<Iter>::difference_type n, const move_iterator<Iter>& x);
 
  template<class Iter>
    constexpr move_iterator<Iter> make_move_iterator(Iter i);
 
  template<Semiregular S> class move_sentinel;
 
  // common iterators
  template<Iterator I, Sentinel<I> S>
    requires (!Same<I, S>)
      class common_iterator;
 
  template<class I, class S>
    struct incrementable_traits<common_iterator<I, S>>;
 
  template<InputIterator I, class S>
    struct iterator_traits<common_iterator<I, S>>;
 
  // default sentinels
  struct default_sentinel_t;
  inline constexpr default_sentinel_t default_sentinel{};
 
  // counted iterators
  template<Iterator I> class counted_iterator;
 
  template<class I>
    struct incrementable_traits<counted_iterator<I>>;
 
  template<InputIterator I>
    struct iterator_traits<counted_iterator<I>>;
 
  // unreachable sentinels
  struct unreachable_sentinel_t;
  inline constexpr unreachable_sentinel_t unreachable_sentinel{};
 
  // stream iterators
  template<class T, class CharT = char, class Traits = char_traits<CharT>,
           class Distance = ptrdiff_t>
  class istream_iterator;
  template<class T, class CharT, class Traits, class Distance>
    bool operator==(const istream_iterator<T, CharT, Traits, Distance>& x,
            const istream_iterator<T, CharT, Traits, Distance>& y);
  template<class T, class CharT, class Traits, class Distance>
    bool operator!=(const istream_iterator<T, CharT, Traits, Distance>& x,
            const istream_iterator<T, CharT, Traits, Distance>& y);
 
  template<class T, class CharT = char, class Traits = char_traits<CharT>>
      class ostream_iterator;
 
  template<class CharT, class Traits = char_traits<CharT>>
    class istreambuf_iterator;
  template<class CharT, class Traits>
    bool operator==(const istreambuf_iterator<CharT, Traits>& a,
            const istreambuf_iterator<CharT, Traits>& b);
  template<class CharT, class Traits>
    bool operator!=(const istreambuf_iterator<CharT, Traits>& a,
            const istreambuf_iterator<CharT, Traits>& b);
 
  template<class CharT, class Traits = char_traits<CharT>>
    class ostreambuf_iterator;
 
  // range access
  template<class C> constexpr auto begin(C& c) -> decltype(c.begin());
  template<class C> constexpr auto begin(const C& c) -> decltype(c.begin());
  template<class C> constexpr auto end(C& c) -> decltype(c.end());
  template<class C> constexpr auto end(const C& c) -> decltype(c.end());
  template<class T, size_t N> constexpr T* begin(T (&a)[N]) noexcept;
  template<class T, size_t N> constexpr T* end(T (&a)[N]) noexcept;
  template<class C> constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c)))
    -> decltype(std::begin(c));
  template<class C> constexpr auto cend(const C& c) noexcept(noexcept(std::end(c)))
    -> decltype(std::end(c));
  template<class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());
  template<class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());
  template<class C> constexpr auto rend(C& c) -> decltype(c.rend());
  template<class C> constexpr auto rend(const C& c) -> decltype(c.rend());
  template<class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&a)[N]);
  template<class T, size_t N> constexpr reverse_iterator<T*> rend(T (&a)[N]);
  template<class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
  template<class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);
  template<class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
  template<class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));
 
  template<class C> constexpr auto size(const C& c) -> decltype(c.size());
  template<class T, size_t N> constexpr size_t size(const T (&a)[N]) noexcept;
  template<class C> constexpr auto ssize(const C& c)
    -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;
  template<class T, ptrdiff_t N> constexpr ptrdiff_t ssize(const T (&a)[N]) noexcept;
  template<class C> [[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty());
  template<class T, size_t N> [[nodiscard]] constexpr bool empty(const T (&a)[N]) noexcept;
  template<class E> [[nodiscard]] constexpr bool empty(initializer_list<E> il) noexcept;
  template<class C> constexpr auto data(C& c) -> decltype(c.data());
  template<class C> constexpr auto data(const C& c) -> decltype(c.data());
  template<class T, size_t N> constexpr T* data(T (&a)[N]) noexcept;
  template<class E> constexpr const E* data(initializer_list<E> il) noexcept;
}

[edit] Concept Readable

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>&>;

[edit] Concept Writable

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
    };

[edit] Concept WeaklyIncrementable

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
        };

[edit] Concept Incrementable

template<class I>
    concept Incrementable =
        Regular<I> &&
        WeaklyIncrementable<I> &&
        requires(I i) {
            { i++ } -> Same<I>;
        };

[edit] Concept Iterator

template<class I>
    concept Iterator =
        requires(I i) {
            { *i } -> __Referenceable;
        } &&
        WeaklyIncrementable<I>;

[edit] Concept Sentinel

template<class S, class I>
    concept Sentinel =
        Semiregular<S> &&
        Iterator<I> &&
        __WeaklyEqualityComparableWith<S, I>; // See [concept.equalitycomparable]

[edit] Concept SizedSentinel

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>>;
        };

[edit] Concept InputIterator

template<class I>
    concept InputIterator =
        Iterator<I> &&
        Readable<I> &&
        requires { typename ITER_CONCEPT(I); } &&
        DerivedFrom<ITER_CONCEPT(I), input_iterator_tag>;

[edit] Concept OutputIterator

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
        };

[edit] Concept ForwardIterator

template<class I>
    concept ForwardIterator =
        InputIterator<I> &&
        DerivedFrom<ITER_CONCEPT(I), forward_iterator_tag> &&
        Incrementable<I> &&
        Sentinel<I, I>;

[edit] Concept BidirectionalIterator

template<class I>
    concept BidirectionalIterator =
        ForwardIterator<I> &&
        DerivedFrom<ITER_CONCEPT(I), bidirectional_iterator_tag> &&
        requires(I i) {
            { --i } -> Same<I&>;
            { i-- } -> Same<I>;
        };

[edit] Concept RandomAccessIterator

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>>;
        };

[edit] Concept ContiguousIterator

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>>>;

[edit] Concept IndirectUnaryInvocable

template<class F, class I>
    concept IndirectUnaryInvocable =
        Readable<I> &&
        CopyConstructible<F> &&
        Invocable<F&, iter_value_t<I>&> &&
        Invocable<F&, iter_reference_t<I>> &&
        Invocable<F&, iter_common_reference_t<I>> &&
        CommonReference<
            invoke_result_t<F&, iter_value_t<I>&>,
            invoke_result_t<F&, iter_reference_t<I>>>;

[edit] Concept IndirectRegularUnaryInvocable

template<class F, class I>
    concept IndirectRegularUnaryInvocable =
        Readable<I> &&
        CopyConstructible<F> &&
        RegularInvocable<F&, iter_value_t<I>&> &&
        RegularInvocable<F&, iter_reference_t<I>> &&
        RegularInvocable<F&, iter_common_reference_t<I>> &&
        CommonReference<
            invoke_result_t<F&, iter_value_t<I>&>,
            invoke_result_t<F&, iter_reference_t<I>>>;

[edit] Concept IndirectUnaryPredicate

template<class F, class I>
    concept IndirectUnaryPredicate =
        Readable<I> &&
        CopyConstructible<F> &&
        Predicate<F&, iter_value_t<I>&> &&
        Predicate<F&, iter_reference_t<I>> &&
        Predicate<F&, iter_common_reference_t<I>>;

[edit] Concept IndirectRelation

template<class F, class I1, class I2 = I1>
    concept IndirectRelation =
        Readable<I1> && Readable<I2> &&
        CopyConstructible<F> &&
        Relation<F&, iter_value_t<I1>&, iter_value_t<I2>&> &&
        Relation<F&, iter_value_t<I1>&, iter_reference_t<I2>> &&
        Relation<F&, iter_reference_t<I1>, iter_value_t<I2>&> &&
        Relation<F&, iter_reference_t<I1>, iter_reference_t<I2>> &&
        Relation<F&, iter_common_reference_t<I1>, iter_common_reference_t<I2>>;

[edit] Concept IndirectStrictWeakOrder

template<class F, class I1, class I2 = I1>
    concept IndirectStrictWeakOrder =
        Readable<I1> && Readable<I2> &&
        CopyConstructible<F> &&
        StrictWeakOrder<F&, iter_value_t<I1>&, iter_value_t<I2>&> &&
        StrictWeakOrder<F&, iter_value_t<I1>&, iter_reference_t<I2>> &&
        StrictWeakOrder<F&, iter_reference_t<I1>, iter_value_t<I2>&> &&
        StrictWeakOrder<F&, iter_reference_t<I1>, iter_reference_t<I2>> &&
        StrictWeakOrder<F&, iter_common_reference_t<I1>, iter_common_reference_t<I2>>;

[edit] Concept IndirectlyMovable

template<class In, class Out>
    concept IndirectlyMovable =
        Readable<In> &&
        Writable<Out, iter_rvalue_reference_t<In>>;

[edit] Concept IndirectlyMovableStorable

template<class In, class Out>
    concept IndirectlyMovableStorable =
        IndirectlyMovable<In, Out> &&
        Writable<Out, iter_value_t<In>> &&
        Movable<iter_value_t<In>> &&
        Constructible<iter_value_t<In>, iter_rvalue_reference_t<In>> &&
        Assignable<iter_value_t<In>&, iter_rvalue_reference_t<In>>;

[edit] Concept IndirectlyCopyable

template<class In, class Out>
    concept IndirectlyCopyable =
        Readable<In> &&
        Writable<Out, iter_reference_t<In>>;

[edit] Concept IndirectlyCopyableStorable

template<class In, class Out>
    concept IndirectlyCopyableStorable =
        IndirectlyCopyable<In, Out> &&
        Writable<Out, const iter_value_t<In>&> &&
        Copyable<iter_value_t<In>> &&
        Constructible<iter_value_t<In>, iter_reference_t<In>> &&
        Assignable<iter_value_t<In>&, iter_reference_t<In>>;

[edit] Concept IndirectlySwappable

template<class I1, class I2 = I1>
    concept IndirectlySwappable =
        Readable<I1> && Readable<I2> &&
        requires(I1& i1, I2& i2) {
            ranges::iter_swap(i1, i1);
            ranges::iter_swap(i2, i2);
            ranges::iter_swap(i1, i2);
            ranges::iter_swap(i2, i1);
        };

[edit] Concept IndirectlyComparable

template<class I1, class I2, class R, class P1 = identity,
         class P2 = identity>
    concept IndirectlyComparable =
        IndirectRelation<R, projected<I1, P1>, projected<I2, P2>>;

[edit] Concept Permutable

template<class I>
    concept Permutable =
        ForwardIterator<I> &&
        IndirectlyMovableStorable<I, I> &&
        IndirectlySwappable<I, I>;

[edit] Concept Mergeable

template<class I1, class I2, class Out, class R = ranges::less,
         class P1 = identity, class P2 = identity>
    concept Mergeable =
        InputIterator<I1> &&
        InputIterator<I2> &&
        WeaklyIncrementable<Out> &&
        IndirectlyCopyable<I1, Out> &&
        IndirectlyCopyable<I2, Out> &&
        IndirectStrictWeakOrder<R, projected<I1, P1>, projected<I2, P2>>;

[edit] Concept Sortable

template<class I, class R = ranges::less, class P = identity>
    concept Sortable =
        Permutable<I> &&
        IndirectStrictWeakOrder<R, projected<I, P>>;

[edit] Class template std::incrementable_traits

template<class> struct incrementable_traits { };
 
template<class T>
    requires is_object_v<T>
struct incrementable_traits<T*> {
    using difference_type = ptrdiff_t;
};
 
template<class I>
struct incrementable_traits<const I>
    : incrementable_traits<I> { };
 
template<class T> requires requires { typename T::difference_type; }
struct incrementable_traits<T> {
    using difference_type = typename T::difference_type;
};
 
template<class T>
    requires (!requires { typename T::difference_type; } &&
               requires(const T& a, const T& b) { { a - b } -> Integral; })
struct incrementable_traits<T> {
    using difference_type = make_signed_t<decltype(declval<T>() - declval<T>())>;
};

[edit] Class template std::readable_traits

template<class> struct __cond_value_type { };   // exposition only
template<class T>
    requires is_object_v<T>
struct __cond_value_type {
    using value_type = remove_cv_t<T>;
};
 
template<class> struct readable_traits { };
 
template<class T>
struct readable_traits<T*>
    : __cond_value_type<T> { };
 
template<class I>
    requires is_array_v<I>
struct readable_traits<I> {
    using value_type = remove_cv_t<remove_extent_t<I>>;
};
 
template<class I>
struct readable_traits<const I>
    : readable_traits<I> { };
 
template<class T>
    requires requires { typename T::value_type; }
struct readable_traits<T>
    : __cond_value_type<typename T::value_type> { };
 
template<class T>
    requires requires { typename T::element_type; }
struct readable_traits<T>
    : __cond_value_type<typename T::element_type> { };

[edit] Class template std::projected

template<Readable I, IndirectRegularUnaryInvocable<I> Proj>
struct projected {
    using value_type = remove_cvref_t<indirect_result_t<Proj&, I>>;
    indirect_result_t<Proj&, I> operator*() const; // not defined
};
 
template<WeaklyIncrementable I, class Proj>
struct incrementable_traits<projected<I, Proj>> {
    using difference_type = iter_difference_t<I>;
};

[edit] Class template std::iterator_traits

template<class It> struct iterator_traits {
    using difference_type   = /* see definition */;
    using value_typet       = /* see definition */;
    using pointer           = /* see definition */;
    using reference         = /* see definition */;
    using iterator_category = /* see definition */;
};
 
template<class T>
    requires is_object_v<T>
struct iterator_traits<T*> {
    using difference_type   = ptrdiff_t;
    using value_type        = remove_cv_t<T>;
    using pointer           = T*;
    using reference         = T&;
    using iterator_concept  = contiguous_iterator_tag;
    using iterator_category = random_access_iterator_tag;
};

[edit] Iterator tags

struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag: public input_iterator_tag { };
struct bidirectional_iterator_tag: public forward_iterator_tag { };
struct random_access_iterator_tag: public bidirectional_iterator_tag { };
struct contiguous_iterator_tag: public random_access_iterator_tag { };

[edit] Class template std::reverse_iterator

template <class It>
class reverse_iterator {
public:
    using iterator_type     = It;
    using iterator_concept  = /* see definition */;
    using iterator_category = /* see definition */;
    using value_type        = iter_value_t<It>;
    using difference_type   = iter_difference_t<It>;
    using pointer           = typename iterator_traits<It>::pointer;
    using reference         = iter_reference_t<It>::reference;
 
    constexpr reverse_iterator();
    constexpr explicit reverse_iterator(It x);
    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
 
    constexpr iterator_type base() const;
    constexpr reference operator*() const;
    constexpr pointer   operator->() const;
 
    constexpr reverse_iterator& operator++();
    constexpr reverse_iterator  operator++(int);
    constexpr reverse_iterator& operator--();
    constexpr reverse_iterator  operator--(int);
 
    constexpr reverse_iterator  operator+ (difference_type n) const;
    constexpr reverse_iterator& operator+=(difference_type n);
    constexpr reverse_iterator  operator- (difference_type n) const;
    constexpr reverse_iterator& operator-=(difference_type n);
 
    constexpr /*unspecified*/ operator[](difference_type n) const;
 
    friend constexpr iter_rvalue_reference_t<It>
        iter_move(const reverse_iterator& i) noexcept(/* see definition */);
    template<IndirectlySwappable<It> It2>
        friend constexpr void
            iter_swap(const reverse_iterator& x,
                      const reverse_iterator<It2>& y) noexcept(/* see definition */);
 
protected:
    It current;
};

[edit] Class template std::back_insert_iterator

template<class Container>
class back_insert_iterator {
protected:
    Container* container = nullptr;
 
public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;
 
    constexpr back_insert_iterator() noexcept = default;
    explicit constexpr back_insert_iterator(Container& x);
    constexpr back_insert_iterator& operator=(const typename Container::value_type& value);
    constexpr back_insert_iterator& operator=(typename Container::value_type&& value);
 
    constexpr back_insert_iterator& operator*();
    constexpr back_insert_iterator& operator++();
    constexpr back_insert_iterator operator++(int);
};

[edit] Class template std::front_insert_iterator

template<class Container>
class front_insert_iterator {
protected:
    Container* container = nullptr;
 
public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;
 
    constexpr front_insert_iterator(Container& x) noexcept = default;
    explicit constexpr front_insert_iterator(Container& x);
    constexpr front_insert_iterator& operator=(const typename Container::value_type& val);
    constexpr front_insert_iterator& operator=(typename Container::value_type&& val);
 
    constexpr front_insert_iterator& operator*();
    constexpr front_insert_iterator& operator++();
    constexpr front_insert_iterator operator++(int);
};

[edit] Class template std::insert_iterator

template<class Container>
class insert_iterator {
protected:
    Container* container = nullptr;
    ranges::iterator_t<Container> iter = ranges::iterator_t<Container>();
 
public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;
 
    insert_iterator() = default;
    constexpr insert_iterator(Container& x, ranges::iterator_t<Container> i);
    constexpr insert_iterator& operator=(const typename Container::value_type& value);
    constexpr insert_iterator& operator=(typename Container::value_type&& value);
 
    constexpr insert_iterator& operator*();
    constexpr insert_iterator& operator++();
    constexpr insert_iterator& operator++(int);
};

[edit] Class template std::move_iterator

template<class It>
class move_iterator {
public:
    using iterator_type     = It;
    using iterator_concept  = input_iterator_tag;
    using iterator_category = /* see definition */;
    using value_type        = iter_value_t<It>;
    using difference_type   = iter_difference_t<It>;
    using pointer           = It;
    using reference         = iter_rvalue_reference_t<It>;
 
    constexpr move_iterator();
    constexpr explicit move_iterator(It i);
    template<class U> constexpr move_iterator(const move_iterator<U>& u);
    template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
 
    constexpr iterator_type base() const;
    constexpr reference operator*() const;
    constexpr pointer operator->() const;
 
    constexpr move_iterator& operator++();
    constexpr move_iterator operator++(int);
    constexpr move_iterator& operator--();
    constexpr move_iterator operator--(int);
 
    constexpr move_iterator operator+(difference_type n) const;
    constexpr move_iterator& operator+=(difference_type n);
    constexpr move_iterator operator-(difference_type n) const;
    constexpr move_iterator& operator-=(difference_type n);
    constexpr reference operator[](difference_type n) const;
 
    template<Sentinel<It> S>
        friend constexpr bool
            operator==(const move_iterator& x, const move_sentinel<S>& y);
    template<Sentinel<It> S>
        friend constexpr bool
            operator==(const move_sentinel<S>& x, const move_iterator& y);
    template<Sentinel<It> S>
        friend constexpr bool
            operator!=(const move_iterator& x, const move_sentinel<S>& y);
    template<Sentinel<It> S>
        friend constexpr bool
            operator!=(const move_sentinel<S>& x, const move_iterator& y);
    template<SizedSentinel<It> S>
        friend constexpr iter_difference_t<It>
            operator-(const move_sentinel<S>& x, const move_iterator& y);
    template<SizedSentinel<It> S>
        friend constexpr iter_difference_t<It>
            operator-(const move_iterator& x, const move_sentinel<S>& y);
    friend constexpr iter_rvalue_reference_t<It>
        iter_move(const move_iterator& i)
            noexcept(noexcept(ranges::iter_move(i.current)));
    template<IndirectlySwappable<It> It2>
        friend constexpr void
            iter_swap(const move_iterator& x, const move_iterator<It2>& y)
                noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
 
private:
    It current; // exposition only
};

[edit] Class template std::move_sentinel

template<Semiregular S>
class move_sentinel {
public:
    constexpr move_sentinel();
    constexpr explicit move_sentinel(S s);
    template<class S2>
        requires ConvertibleTo<const S2&, S>
            constexpr move_sentinel(const move_sentinel<S2>& s);
    template<class S2>
        requires Assignable<S&, const S2&>
            constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
 
    constexpr S base() const;
private:
    S last;     // exposition only
};

[edit] Class template std::common_iterator

template<Iterator I, Sentinel<I> S>
    requires (!Same<I, S>)
class common_iterator {
public:
    constexpr common_iterator() = default;
    constexpr common_iterator(I i);
    constexpr common_iterator(S s);
    template<class I2, class S2>
        requires ConvertibleTo<const I2&, I> && ConvertibleTo<const S2&, S>
            constexpr common_iterator(const common_iterator<I2, S2>& x);
 
    template<class I2, class S2>
        requires ConvertibleTo<const I2&, I> && ConvertibleTo<const S2&, S> &&
                 Assignable<I&, const I2&> && Assignable<S&, const S2&>
            common_iterator& operator=(const common_iterator<I2, S2>& x);
 
    decltype(auto) operator*();
    decltype(auto) operator*() const
        requires __Dereferenceable<const I>;
    decltype(auto) operator->() const
        requires /* see definition */;
 
    common_iterator& operator++();
    decltype(auto) operator++(int);
 
    template<class I2, Sentinel<I> S2>
        requires Sentinel<S, I2>
    friend bool operator==(
        const common_iterator& x, const common_iterator<I2, S2>& y);
    template<class I2, Sentinel<I> S2>
      requires Sentinel<S, I2> && EqualityComparableWith<I, I2>
    friend bool operator==(
        const common_iterator& x, const common_iterator<I2, S2>& y);
    template<class I2, Sentinel<I> S2>
        requires Sentinel<S, I2>
    friend bool operator!=(
        const common_iterator& x, const common_iterator<I2, S2>& y);
 
    template<SizedSentinel<I> I2, SizedSentinel<I> S2>
        requires SizedSentinel<S, I2>
    friend iter_difference_t<I2> operator-(
        const common_iterator& x, const common_iterator<I2, S2>& y);
 
    friend iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
        noexcept(noexcept(ranges::iter_move(declval<const I&>())))
            requires InputIterator<I>;
    template<IndirectlySwappable<I> I2, class S2>
        friend void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
            noexcept(noexcept(
                ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
 
private:
    variant<I, S> v_;   // exposition only
};
 
template<class I, class S>
struct incrementable_traits<common_iterator<I, S>> {
    using difference_type = iter_difference_t<I>;
};
 
template<InputIterator I, class S>
struct iterator_traits<common_iterator<I, S>> {
    using iterator_concept = /* see definition */;
    using iterator_category = /* see definition */;
    using value_type = iter_value_t<I>;
    using difference_type = iter_difference_t<I>;
    using pointer = /* see definition */;
    using reference = iter_reference_t<I>;
};

[edit] Class std::default_sentinel_t

struct default_sentinel_t { };

[edit] Class template std::counted_iterator

template<Iterator I>
class counted_iterator {
public:
    using iterator_type = I;
 
    constexpr counted_iterator() = default;
    constexpr counted_iterator(I x, iter_difference_t<I> n);
    template<class I2>
        requires ConvertibleTo<const I2&, I>
            constexpr counted_iterator(const counted_iterator<I2>& x);
 
    template<class I2>
        requires Assignable<I&, const I2&>
            constexpr counted_iterator& operator=(const counted_iterator<I2>& x);
 
    constexpr I base() const;
    constexpr iter_difference_t<I> count() const noexcept;
    constexpr decltype(auto) operator*();
    constexpr decltype(auto) operator*() const
        requires __Dereferenceable<const I>;
 
    constexpr counted_iterator& operator++();
    decltype(auto) operator++(int);
    constexpr counted_iterator operator++(int)
        requires ForwardIterator<I>;
    constexpr counted_iterator& operator--()
        requires BidirectionalIterator<I>;
    constexpr counted_iterator operator--(int)
        requires BidirectionalIterator<I>;
 
    constexpr counted_iterator operator+(iter_difference_t<I> n) const
        requires RandomAccessIterator<I>;
    friend constexpr counted_iterator operator+(
        iter_difference_t<I> n, const counted_iterator& x)
            requires RandomAccessIterator<I>;
    constexpr counted_iterator& operator+=(iter_difference_t<I> n)
        requires RandomAccessIterator<I>;
 
    constexpr counted_iterator operator-(iter_difference_t<I> n) const
        requires RandomAccessIterator<I>;
    template<Common<I> I2>
        friend constexpr iter_difference_t<I2> operator-(
            const counted_iterator& x, const counted_iterator<I2>& y);
    friend constexpr iter_difference_t<I> operator-(
        const counted_iterator& x, default_sentinel_t);
    friend constexpr iter_difference_t<I> operator-(
        default_sentinel_t, const counted_iterator& y);
    constexpr counted_iterator& operator-=(iter_difference_t<I> n)
        requires RandomAccessIterator<I>;
 
    constexpr decltype(auto) operator[](iter_difference_t<I> n) const
        requires RandomAccessIterator<I>;
 
    template<Common<I> I2>
        friend constexpr bool operator==(
            const counted_iterator& x, const counted_iterator<I2>& y);
    friend constexpr bool operator==(
        const counted_iterator& x, default_sentinel_t);
    friend constexpr bool operator==(
        default_sentinel_t, const counted_iterator& x);
 
    template<Common<I> I2>
        friend constexpr bool operator!=(
            const counted_iterator& x, const counted_iterator<I2>& y);
    friend constexpr bool operator!=(
        const counted_iterator& x, default_sentinel_t y);
    friend constexpr bool operator!=(
        default_sentinel_t x, const counted_iterator& y);
 
    template<Common<I> I2>
        friend constexpr bool operator<(
            const counted_iterator& x, const counted_iterator<I2>& y);
    template<Common<I> I2>
        friend constexpr bool operator>(
            const counted_iterator& x, const counted_iterator<I2>& y);
    template<Common<I> I2>
        friend constexpr bool operator<=(
            const counted_iterator& x, const counted_iterator<I2>& y);
    template<Common<I> I2>
        friend constexpr bool operator>=(
            const counted_iterator& x, const counted_iterator<I2>& y);
 
    friend constexpr iter_rvalue_reference_t<I> iter_move(const counted_iterator& i)
        noexcept(noexcept(ranges::iter_move(i.current)))
            requires InputIterator<I>;
    template<IndirectlySwappable<I> I2>
        friend constexpr void iter_swap(const counted_iterator& x,
                                        const counted_iterator<I2>& y)
            noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
 
private:
    I current = I();                    // exposition only
    iter_difference_t<I> length = 0;    // exposition only
};
 
template<class I>
struct incrementable_traits<counted_iterator<I>> {
    using difference_type = iter_difference_t<I>;
};
 
template<InputIterator I>
struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {
    using pointer = void;
};

[edit] Class std::unreachable_sentinel_t

struct unreachable_sentinel_t {
    template<WeaklyIncrementable I>
        friend constexpr bool operator==(unreachable_sentinel_t, const I&) noexcept;
    template<WeaklyIncrementable I>
        friend constexpr bool operator==(const I&, unreachable_sentinel_t) noexcept;
    template<WeaklyIncrementable I>
        friend constexpr bool operator!=(unreachable_sentinel_t, const I&) noexcept;
    template<WeaklyIncrementable I>
        friend constexpr bool operator!=(const I&, unreachable_sentinel_t) noexcept;
};

[edit] Class template std::istream_iterator

template<class T, class CharT = char, class Traits = char_traits<CharT>,
         class Distance = ptrdiff_t>
class istream_iterator {
public:
    using iterator_category = input_iterator_tag;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = const T*;
    using reference         = const T&;
    using char_type         = CharT;
    using traits_type       = Traits;
    using istream_type      = basic_istream<CharT, Traits>;
 
    constexpr istream_iterator();
    istream_iterator(istream_type& s);
    istream_iterator(const istream_iterator& x) = default;
    ~istream_iterator() = default;
 
    const T& operator*() const;
    const T* operator->() const;
    istream_iterator& operator++();
    istream_iterator operator++(int);
 
private:
    basic_istream<CharT, Traits>* in_stream; // exposition only
    T value;                                 // exposition only
};

[edit] Class template std::ostream_iterator

template<class T, class CharT = char, class Traits = char_traits<CharT>>
class ostream_iterator {
public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using char_type         = CharT;
    using traits_type       = Traits;
    using ostream_type      = basic_ostream<CharT, Traits>;
 
    ostream_iterator(ostream_type& s);
    ostream_iterator(ostream_type& s, const CharT* delimiter);
    ostream_iterator(const ostream_iterator& x);
    ~ostream_iterator();
 
    ostream_iterator& operator=(const T& value);
    ostream_iterator& operator*();
    ostream_iterator& operator++();
    ostream_iterator& operator++(int);
 
private:
    basic_ostream<CharT, Traits>* out_stream; // exposition only
    const CharT* delim;                       // exposition only
};

[edit] Class template std::istreambuf_iterator

template<class CharT, class Traits = char_traits<CharT>>
class istreambuf_iterator {
public:
    using iterator_category = input_iterator_tag;
    using value_type        = CharT;
    using difference_type   = typename Traits::off_type;
    using pointer           = /*unspecified*/;
    using reference         = CharT;
    using char_type         = CharT;
    using traits_type       = Traits;
    using int_type          = typename Traits::int_type;
    using streambuf_type    = basic_streambuf<CharT, Traits>;
    using istream_type      = basic_istream<CharT, Traits>;
 
    class proxy; // exposition only
 
    constexpr istreambuf_iterator() noexcept;
    istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
    ~istreambuf_iterator() = default;
 
    istreambuf_iterator(istream_type& s) noexcept;
    istreambuf_iterator(streambuf_type* s) noexcept;
    istreambuf_iterator(const proxy& p) noexcept;
    CharT operator*() const;
    istreambuf_iterator& operator++();
    proxy operator++(int);
    bool equal(const istreambuf_iterator& b) const;
 
private:
    streambuf_type* sbuf_; // exposition only
};
 
template<class CharT, class Traits = char_traits<CharT>>
class istreambuf_iterator<CharT, Traits>::proxy { // exposition only
    CharT keep_;
    basic_streambuf<CharT, Traits>* sbuf_;
    proxy(CharT c, basic_streambuf<CharT, Traits>* sbuf)
        : keep_(c), sbuf_(sbuf) { }
public:
    CharT operator*() { return keep_; }
};

[edit] Class template std::ostreambuf_iterator

template<class CharT, class Traits = char_traits<CharT>>
class ostreambuf_iterator {
public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using char_type         = CharT;
    using traits_type       = Traits;
    using streambuf_type    = basic_streambuf<CharT, Traits>;
    using ostream_type      = basic_ostream<CharT, Traits>;
 
    ostreambuf_iterator(ostream_type& s) noexcept;
    ostreambuf_iterator(streambuf_type* s) noexcept;
    ostreambuf_iterator& operator=(CharT c);
 
    ostreambuf_iterator& operator*();
    ostreambuf_iterator& operator++();
    ostreambuf_iterator& operator++(int);
    bool failed() const noexcept;
 
private:
    streambuf_type* sbuf_; // exposition only
};

[edit] Class template std::iterator

template<class Category, class T, class Distance = ptrdiff_t,
         class Pointer = T*, class Reference = T&>
struct iterator {
    typedef T           value_type;
    typedef Distance    difference_type;
    typedef Pointer     pointer;
    typedef Reference   reference;
    typedef Category    iterator_category;
};