9 Iterators library [iterators]

9.2 Header <experimental/ranges/iterator> synopsis [iterator.synopsis]

namespace std { namespace experimental { namespace ranges { inline namespace v1 {
  template <class T> concept bool dereferenceable // exposition only
    = requires(T& t) { {*t} -> auto&&; };

  // [iterator.requirements], iterator requirements:
  // [iterator.custpoints], customization points:
  namespace {
    // [iterator.custpoints.iter_move], iter_move:
    constexpr unspecified iter_move = unspecified;

    // [iterator.custpoints.iter_swap], iter_swap:
    constexpr unspecified iter_swap = unspecified;
  }

  // [iterator.assoc.types], associated types:
  // [iterator.assoc.types.difference_type], difference_type:
  template <class> struct difference_type;
  template <class T> using difference_type_t
    = typename difference_type<T>::type;

  // [iterator.assoc.types.value_type], value_type:
  template <class> struct value_type;
  template <class T> using value_type_t
    = typename value_type<T>::type;

  // [iterator.assoc.types.iterator_category], iterator_category:
  template <class> struct iterator_category;
  template <class T> using iterator_category_t
    = typename iterator_category<T>::type;

  template <dereferenceable T> using reference_t
    = decltype(*declval<T&>());

  template <dereferenceable T>
      requires see below using rvalue_reference_t
    = decltype(ranges::iter_move(declval<T&>()));

  // [iterators.readable], Readable:
  template <class In>
  concept bool Readable = see below;

  // [iterators.writable], Writable:
  template <class Out, class T>
  concept bool Writable = see below;

  // [iterators.weaklyincrementable], WeaklyIncrementable:
  template <class I>
  concept bool WeaklyIncrementable = see below;

  // [iterators.incrementable], Incrementable:
  template <class I>
  concept bool Incrementable = see below;

  // [iterators.iterator], Iterator:
  template <class I>
  concept bool Iterator = see below;

  // [iterators.sentinel], Sentinel:
  template <class S, class I>
  concept bool Sentinel = see below;

  // [iterators.sizedsentinel], SizedSentinel:
  template <class S, class I>
    constexpr bool disable_sized_sentinel = false;

  template <class S, class I>
  concept bool SizedSentinel = see below;

  // [iterators.input], InputIterator:
  template <class I>
  concept bool InputIterator = see below;

  // [iterators.output], OutputIterator:
  template <class I>
  concept bool OutputIterator = see below;

  // [iterators.forward], ForwardIterator:
  template <class I>
  concept bool ForwardIterator = see below;

  // [iterators.bidirectional], BidirectionalIterator:
  template <class I>
  concept bool BidirectionalIterator = see below;

  // [iterators.random.access], RandomAccessIterator:
  template <class I>
  concept bool RandomAccessIterator = see below;

  // [indirectcallable], indirect callable requirements:
  // [indirectcallable.indirectinvocable], indirect callables:
  template <class F, class I>
  concept bool IndirectUnaryInvocable = see below;

  template <class F, class I>
  concept bool IndirectRegularUnaryInvocable = see below;

  template <class F, class I>
  concept bool IndirectUnaryPredicate = see below;

  template <class F, class I1, class I2 = I1>
  concept bool IndirectRelation = see below;

  template <class F, class I1, class I2 = I1>
  concept bool IndirectStrictWeakOrder = see below;

  template <class> struct indirect_result_of;

  template <class F, class... Is>
    requires Invocable<F, reference_t<Is>...>
  struct indirect_result_of<F(Is...)>;

  template <class F>
  using indirect_result_of_t
    = typename indirect_result_of<F>::type;

  // [projected], projected:
  template <Readable I, IndirectRegularUnaryInvocable<I> Proj>
  struct projected;

  template <WeaklyIncrementable I, class Proj>
  struct difference_type<projected<I, Proj>>;

  // [commonalgoreq], common algorithm requirements:
  // [commonalgoreq.indirectlymovable] IndirectlyMovable:
  template <class In, class Out>
  concept bool IndirectlyMovable = see below;

  template <class In, class Out>
  concept bool IndirectlyMovableStorable = see below;

  // [commonalgoreq.indirectlycopyable] IndirectlyCopyable:
  template <class In, class Out>
  concept bool IndirectlyCopyable = see below;

  template <class In, class Out>
  concept bool IndirectlyCopyableStorable = see below;

  // [commonalgoreq.indirectlyswappable] IndirectlySwappable:
  template <class I1, class I2 = I1>
  concept bool IndirectlySwappable = see below;

  // [commonalgoreq.indirectlycomparable] IndirectlyComparable:
  template <class I1, class I2, class R = equal_to<>, class P1 = identity,
      class P2 = identity>
  concept bool IndirectlyComparable = see below;

  // [commonalgoreq.permutable] Permutable:
  template <class I>
  concept bool Permutable = see below;

  // [commonalgoreq.mergeable] Mergeable:
  template <class I1, class I2, class Out,
      class R = less<>, class P1 = identity, class P2 = identity>
  concept bool Mergeable = see below;

  template <class I, class R = less<>, class P = identity>
  concept bool Sortable = see below;

  // [iterator.primitives], primitives:
  // [iterator.traits], traits:
  template <class Iterator> using iterator_traits = see below;

  template <Readable T> using iter_common_reference_t
    = common_reference_t<reference_t<T>, value_type_t<T>&>;

  // [std.iterator.tags], iterator tags:
  struct output_iterator_tag { };
  struct input_iterator_tag { };
  struct forward_iterator_tag : input_iterator_tag { };
  struct bidirectional_iterator_tag : forward_iterator_tag { };
  struct random_access_iterator_tag : bidirectional_iterator_tag { };

  // [iterator.operations], iterator operations:
  namespace {
    constexpr unspecified advance = unspecified;
    constexpr unspecified distance = unspecified;
    constexpr unspecified next = unspecified;
    constexpr unspecified prev = unspecified;
  }

  // [iterators.predef], predefined iterators and sentinels:

  // [iterators.reverse], reverse iterators:
  template <BidirectionalIterator I> class reverse_iterator;

  template <class I1, class I2>
      requires EqualityComparableWith<I1, I2>
    constexpr bool operator==(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires EqualityComparableWith<I1, I2>
    constexpr bool operator!=(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator<(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator>(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator>=(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator<=(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);

  template <class I1, class I2>
      requires SizedSentinel<I1, I2>
    constexpr difference_type_t<I2> operator-(
      const reverse_iterator<I1>& x,
      const reverse_iterator<I2>& y);
  template <RandomAccessIterator I>
    constexpr reverse_iterator<I> operator+(
      difference_type_t<I> n,
      const reverse_iterator<I>& x);

  template <BidirectionalIterator I>
    constexpr reverse_iterator<I> make_reverse_iterator(I i);

  // [iterators.insert], insert iterators:
  template <class Container> class back_insert_iterator;
  template <class Container>
    back_insert_iterator<Container> back_inserter(Container& x);

  template <class Container> class front_insert_iterator;
  template <class Container>
    front_insert_iterator<Container> front_inserter(Container& x);

  template <class Container> class insert_iterator;
  template <class Container>
    insert_iterator<Container> inserter(Container& x, iterator_t<Container> i);

  // [iterators.move], move iterators and sentinels:
  template <InputIterator I> class move_iterator;
  template <class I1, class I2>
      requires EqualityComparableWith<I1, I2>
    constexpr bool operator==(
      const move_iterator<I1>& x, const move_iterator<I2>& y);
  template <class I1, class I2>
      requires EqualityComparableWith<I1, I2>
    constexpr bool operator!=(
      const move_iterator<I1>& x, const move_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator<(
      const move_iterator<I1>& x, const move_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator<=(
      const move_iterator<I1>& x, const move_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator>(
      const move_iterator<I1>& x, const move_iterator<I2>& y);
  template <class I1, class I2>
      requires StrictTotallyOrderedWith<I1, I2>
    constexpr bool operator>=(
      const move_iterator<I1>& x, const move_iterator<I2>& y);

  template <class I1, class I2>
      requires SizedSentinel<I1, I2>
    constexpr difference_type_t<I2> operator-(
      const move_iterator<I1>& x,
      const move_iterator<I2>& y);
  template <RandomAccessIterator I>
    constexpr move_iterator<I> operator+(
      difference_type_t<I> n,
      const move_iterator<I>& x);
  template <InputIterator I>
    constexpr move_iterator<I> make_move_iterator(I i);

  template <Semiregular S> class move_sentinel;

  template <class I, Sentinel<I> S>
    constexpr bool operator==(
      const move_iterator<I>& i, const move_sentinel<S>& s);
  template <class I, Sentinel<I> S>
    constexpr bool operator==(
      const move_sentinel<S>& s, const move_iterator<I>& i);
  template <class I, Sentinel<I> S>
    constexpr bool operator!=(
      const move_iterator<I>& i, const move_sentinel<S>& s);
  template <class I, Sentinel<I> S>
    constexpr bool operator!=(
      const move_sentinel<S>& s, const move_iterator<I>& i);

  template <class I, SizedSentinel<I> S>
    constexpr difference_type_t<I> operator-(
      const move_sentinel<S>& s, const move_iterator<I>& i);
  template <class I, SizedSentinel<I> S>
    constexpr difference_type_t<I> operator-(
      const move_iterator<I>& i, const move_sentinel<S>& s);

  template <Semiregular S>
    constexpr move_sentinel<S> make_move_sentinel(S s);

  // [iterators.common], common iterators:
  template <Iterator I, Sentinel<I> S>
    requires !Same<I, S>
  class common_iterator;

  template <Readable I, class S>
  struct value_type<common_iterator<I, S>>;

  template <InputIterator I, class S>
  struct iterator_category<common_iterator<I, S>>;

  template <ForwardIterator I, class S>
  struct iterator_category<common_iterator<I, S>>;

  template <class I1, class I2, Sentinel<I2> S1, Sentinel<I1> S2>
  bool operator==(
    const common_iterator<I1, S1>& x, const common_iterator<I2, S2>& y);
  template <class I1, class I2, Sentinel<I2> S1, Sentinel<I1> S2>
    requires EqualityComparableWith<I1, I2>
  bool operator==(
    const common_iterator<I1, S1>& x, const common_iterator<I2, S2>& y);
  template <class I1, class I2, Sentinel<I2> S1, Sentinel<I1> S2>
  bool operator!=(
    const common_iterator<I1, S1>& x, const common_iterator<I2, S2>& y);

  template <class I2, SizedSentinel<I2> I1, SizedSentinel<I2> S1, SizedSentinel<I1> S2>
  difference_type_t<I2> operator-(
    const common_iterator<I1, S1>& x, const common_iterator<I2, S2>& y);

  // [default.sentinels], default sentinels:
  class default_sentinel;

  // [iterators.counted], counted iterators:
  template <Iterator I> class counted_iterator;

  template <class I1, class I2>
      requires Common<I1, I2>
    constexpr bool operator==(
      const counted_iterator<I1>& x, const counted_iterator<I2>& y);
  constexpr bool operator==(
    const counted_iterator<auto>& x, default_sentinel);
  constexpr bool operator==(
    default_sentinel, const counted_iterator<auto>& x);
  template <class I1, class I2>
      requires Common<I1, I2>
    constexpr bool operator!=(
      const counted_iterator<I1>& x, const counted_iterator<I2>& y);
  constexpr bool operator!=(
    const counted_iterator<auto>& x, default_sentinel y);
  constexpr bool operator!=(
    default_sentinel x, const counted_iterator<auto>& y);
  template <class I1, class I2>
      requires Common<I1, I2>
    constexpr bool operator<(
      const counted_iterator<I1>& x, const counted_iterator<I2>& y);
  template <class I1, class I2>
      requires Common<I1, I2>
    constexpr bool operator<=(
      const counted_iterator<I1>& x, const counted_iterator<I2>& y);
  template <class I1, class I2>
      requires Common<I1, I2>
    constexpr bool operator>(
      const counted_iterator<I1>& x, const counted_iterator<I2>& y);
  template <class I1, class I2>
      requires Common<I1, I2>
    constexpr bool operator>=(
      const counted_iterator<I1>& x, const counted_iterator<I2>& y);
  template <class I1, class I2>
      requires Common<I1, I2>
    constexpr difference_type_t<I2> operator-(
      const counted_iterator<I1>& x, const counted_iterator<I2>& y);
  template <class I>
    constexpr difference_type_t<I> operator-(
      const counted_iterator<I>& x, default_sentinel y);
  template <class I>
    constexpr difference_type_t<I> operator-(
      default_sentinel x, const counted_iterator<I>& y);
  template <RandomAccessIterator I>
    constexpr counted_iterator<I>
      operator+(difference_type_t<I> n, const counted_iterator<I>& x);
  template <Iterator I>
    constexpr counted_iterator<I> make_counted_iterator(I i, difference_type_t<I> n);

  // [unreachable.sentinels], unreachable sentinels:
  class unreachable;
  template <Iterator I>
    constexpr bool operator==(const I&, unreachable) noexcept;
  template <Iterator I>
    constexpr bool operator==(unreachable, const I&) noexcept;
  template <Iterator I>
    constexpr bool operator!=(const I&, unreachable) noexcept;
  template <Iterator I>
    constexpr bool operator!=(unreachable, const I&) noexcept;

  // [dangling.wrappers], dangling wrapper:
  template <class T> class dangling;

  // [iterators.stream], 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==(default_sentinel 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,
            default_sentinel 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, class traits, class Distance>
   bool operator!=(default_sentinel 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,
            default_sentinel 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==(default_sentinel a,
            const istreambuf_iterator<charT, traits>& b);
  template <class charT, class traits>
    bool operator==(const istreambuf_iterator<charT, traits>& a,
            default_sentinel 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>
    bool operator!=(default_sentinel a,
            const istreambuf_iterator<charT, traits>& b);
  template <class charT, class traits>
    bool operator!=(const istreambuf_iterator<charT, traits>& a,
            default_sentinel b);

  template <class charT, class traits = char_traits<charT> >
    class ostreambuf_iterator;
}}}}

namespace std {
  // [iterator.stdtraits], iterator traits:
  template <experimental::ranges::Iterator Out>
    struct iterator_traits<Out>;
  template <experimental::ranges::InputIterator In>
    struct iterator_traits<In>;
  template <experimental::ranges::InputIterator In>
      requires experimental::ranges::Sentinel<In, In>
    struct iterator_traits;
}