# Standard library header <iterator>

From cppreference.com
< cpp‎ | header

This header is part of the iterator library.

### Concepts

##### Iterator concepts

Readable | specifies that a type is readable by applying operator `*` (concept)
Writable | specifies that a value can be written to an iterator's referenced object (concept)
WeaklyIncrementable | specifies that a `Semiregular` type can be incremented with pre- and post-increment operators (concept)
Incrementable | specifies that the increment operation on a `WeaklyIncrementable` type is equality-preserving and that the type is `EqualityComparable` (concept)
Iterator | specifies that objects of a type can be incremented and dereferenced (concept)
Sentinel | specifies a type is a sentinel for an `Iterator` type (concept)
SizedSentinel | specifies that the - operator can be applied to an iterator and a sentinel to calculate their difference in constant time (concept)
InputIterator | 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)
OutputIterator | 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)
ForwardIterator | specifies that an `InputIterator` is a forward iterator, supporting equality comparison and multi-pass (concept)
BidirectionalIterator | specifies that a `ForwardIterator` is a bidirectional interator, supporting movement backwards (concept)
RandomAccessIterator | specifies that a `BidirectionalIterator` is a random-access iterator, supporting advancement in constant time and subscripting (concept)
ContiguousIterator | specifies that a `RandomAccessIterator` is a contiguous iterator, referring to elements that are contiguous in memory (concept)

##### Indirect callable concepts

IndirectUnaryInvocable IndirectRegularUnaryInvocable | specifies that a callable type can be invoked with the result of dereferencing a `Readable` type (concept)
IndirectUnaryPredicate | specifies that a callable type, when invoked with the result of dereferencing a `Readable` type, satisfies `Predicate` (concept)
IndirectRelation | specifies that a callable type, when invoked with the result of dereferencing two `Readable` types, satisfies `Predicate` (concept)
IndirectStrictWeakOrder | specifies that a callable type, when invoked with the result of dereferencing two `Readable` types, satisfies `StrictWeakOrder` (concept)

##### Common algorithm requirements

IndirectlyMovable | specifies that values may be moved from a `Readable` type to a `Writable` type (concept)
IndirectlyMovableStorable | 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)
IndirectlyCopyable | specifies that values may be copied from a `Readable` type to a `Writable` type (concept)
IndirectlyCopyableStorable | 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)
IndirectlySwappable | specifies that the values referenced by two `Readable` types can be swapped (concept)
IndirectlyComparable | specifies that the values referenced by two `Readable` types can be compared (concept)
Permutable | specifies the common requirements of algorithms that reorder elements in place (concept)
Mergeable | specifies the requirements of algorithms that merge sorted sequences into an output sequence by copying elements (concept)
Sortable | specifies the common requirements of algorithms that permute sequences into ordered sequences (concept)

### Classes

##### Algorithm utilities

indirect_result_t | computes the result of invoking a callable object on the result of dereferencing some set of `Readable` types (alias template)
projected | helper template for specifying the constraints on algorithms that accept projections (class template)

##### Associated types

incrementable_traits | computes the difference type of a `WeaklyIncrementable` type (class template)
readable_traits | computes the value type of a `Readable` type (class template)
iter_value_t iter_reference_t iter_difference_t iter_rvalue_reference_t iter_common_reference_t | computes the associate types of an iterator (alias template)

##### Primitives

iterator_traits | provides uniform interface to the properties of an iterator (class template)
input_iterator_tag output_iterator_tag forward_iterator_tag bidirectional_iterator_tag random_access_iterator_tag contiguous_iterator_tag (C++20) | empty class types used to indicate iterator categories (class)
iterator (deprecated in C++17) | base class to ease the definition of required types for simple iterators (class template)

##### Adaptors

reverse_iterator | iterator adaptor for reverse-order traversal (class template)
move_iterator (C++11) | iterator adaptor which dereferences to an rvalue reference (class template)
move_sentinel (C++20) | sentinel adaptor for use with std::move_iterator (class template)
common_iterator (C++20) | adapts an iterator type and its sentinel into a common iterator type (class template)
default_sentinel_t (C++20) | default sentinel for use with iterators that know the bound of their range (class)
counted_iterator (C++20) | iterator adaptor that tracks the distance to the end of the range (class template)
unreachable_sentinel_t (C++20) | sentinel that always compares unequal to any `WeaklyIncrementable` type (class)
back_insert_iterator | iterator adaptor for insertion at the end of a container (class template)
front_insert_iterator | iterator adaptor for insertion at the front of a container (class template)
insert_iterator | iterator adaptor for insertion into a container (class template)

##### Stream Iterators

istream_iterator | input iterator that reads from std::basic_istream (class template)
ostream_iterator | output iterator that writes to std::basic_ostream (class template)
istreambuf_iterator | input iterator that reads from std::basic_streambuf (class template)
ostreambuf_iterator | output iterator that writes to std::basic_streambuf (class template)

### Customization point objects

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

### Functions

##### Adaptors

make_reverse_iterator (C++14) | creates a std::reverse_iterator of type inferred from the argument (function template)
make_move_iterator (C++11) | creates a std::move_iterator of type inferred from the argument (function template)
front_inserter | creates a std::front_insert_iterator of type inferred from the argument (function template)
back_inserter | creates a std::back_insert_iterator of type inferred from the argument (function template)
inserter | creates a std::insert_iterator of type inferred from the argument (function template)

##### Non-member operators

operator==operator!=operator<operator<=operator>operator>= | compares the underlying iterators (function template)
operator+ | advances the iterator (function template)
operator- | computes the distance between two iterator adaptors (function template)
operator==operator!=operator<operator<=operator>operator>= | compares the underlying iterators (function template)
operator+ | advances the iterator (function template)
operator- | computes the distance between two iterator adaptors (function template)
operator==operator!= | compares two `istream_iterator`s (function template)
operator==operator!= | compares two `istreambuf_iterator`s (function template)

##### Operations

advance | advances an iterator by given distance (function template)
distance | returns the distance between two iterators (function template)
next (C++11) | increment an iterator (function template)
prev (C++11) | decrement an iterator (function template)
ranges::advance (C++20) | advances an iterator by given distance or to a given bound (niebloid)
ranges::distance (C++20) | returns the distance between an iterator and a sentinel, or between the beginning and end of a range (niebloid)
ranges::next (C++20) | increment an iterator by a given distance or to a bound (niebloid)
ranges::prev (C++20) | decrement an iterator by a given distance or to a bound (niebloid)

##### Range access

begin cbegin (C++11)(C++14) | returns an iterator to the beginning of a container or array (function template)
end cend (C++11)(C++14) | returns an iterator to the end of a container or array (function template)
rbegin crbegin (C++14) | returns a reverse iterator to a container or array (function template)
rend crend (C++14) | returns a reverse end iterator for a container or array (function template)
size ssize (C++17)(C++20) | returns the size of a container or array (function template)
empty (C++17) | checks whether the container is empty (function template)
data (C++17) | obtains the pointer to the underlying array (function template)

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

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

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

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

#### Concept `Incrementable`

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

#### Concept `Iterator`

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

#### Concept `Sentinel`

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

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

#### Concept `InputIterator`

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

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

#### Concept `ForwardIterator`

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

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

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

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

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

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

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

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

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

#### Concept `IndirectlyMovable`

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

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

#### Concept `IndirectlyCopyable`

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

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

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

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

#### Concept `Permutable`

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

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

#### Concept `Sortable`

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

#### 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>())>;
    };

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

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

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

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

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

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

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

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

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

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

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

#### Class std::default_sentinel_t

    struct default_sentinel_t { };

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

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

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

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

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

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

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

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/header/iterator&oldid=110687"