9 Iterators library [iterators]

9.6 Iterator primitives [iterator.primitives]

9.6.4 Iterator operations [iterator.operations]

Since only types that satisfy RandomAccessIterator provide the + operator, and types that satisfy SizedSentinel provide the - operator, the library provides customization point objects ([customization.point.object]) advance, distance, next, and prev. These customization point objects use + and - for random access iterators and ranges that satisfy SizedSentinel (and are, therefore, constant time for them); for output, input, forward and bidirectional iterators they use ++ to provide linear time implementations.

The name advance denotes a customization point object ([customization.point.object]). It has the following function call operators:

template <Iterator I> constexpr void operator()(I& i, difference_type_t<I> n) const;

Requires: n shall be negative only for bidirectional iterators.

Effects: For random access iterators, equivalent to i += n. Otherwise, increments (or decrements for negative n) iterator i by n.

template <Iterator I, Sentinel<I> S> constexpr void operator()(I& i, S bound) const;

Requires: If Assignable<I&, S> is not satisfied, [i,bound) shall denote a range.

Effects:

  • If Assignable<I&, S> is satisfied, equivalent to i = std::move(bound).

  • Otherwise, if SizedSentinel<S, I> is satisfied, equivalent to advance(i, bound - i).

  • Otherwise, increments i until i == bound.

template <Iterator I, Sentinel<I> S> constexpr difference_type_t<I> operator()(I& i, difference_type_t<I> n, S bound) const;

Requires: If n > 0, [i,bound) shall denote a range. If n == 0, [i,bound) or [bound,i) shall denote a range. If n < 0, [bound,i) shall denote a range and (BidirectionalIterator<I> && Same<I, S>) shall be satisfied.

Effects:

  • If SizedSentinel<S, I> is satisfied:

    • If |n| >= |bound - i|, equivalent to advance(i, bound).

    • Otherwise, equivalent to advance(i, n).

  • Otherwise, increments (or decrements for negative n) iterator i either n times or until i == bound, whichever comes first.

Returns: n - M, where M is the distance from the starting position of i to the ending position.

The name distance denotes a customization point object. It has the following function call operators:

template <Iterator I, Sentinel<I> S> constexpr difference_type_t<I> operator()(I first, S last) const;

Requires: [first,last) shall denote a range, or (Same<S, I> && SizedSentinel<S, I>) shall be satisfied and [last,first) shall denote a range.

Effects: If SizedSentinel<S, I> is satisfied, returns (last - first); otherwise, returns the number of increments needed to get from first to last.

template <Range R> constexpr difference_type_t<iterator_t<R>> operator()(R&& r) const;

Effects: Equivalent to: return distance(ranges::begin(r), ranges::end(r)); ([range.access])

Remarks: Instantiations of this member function template may be ill-formed if the declarations in <experimental/ranges/range> are not in scope at the point of instantiation ( ISO/IEC 14882:2014 §[temp.point]).

template <SizedRange R> constexpr difference_type_t<iterator_t<R>> operator()(R&& r) const;

Effects: Equivalent to: return ranges::size(r); ([range.primitives.size])

Remarks: Instantiations of this member function template may be ill-formed if the declarations in <experimental/ranges/range> are not in scope at the point of instantiation ( ISO/IEC 14882:2014 §[temp.point]).

The name next denotes a customization point object. It has the following function call operators:

template <Iterator I> constexpr I operator()(I x) const;

Effects: Equivalent to: ++x; return x;

template <Iterator I> constexpr I operator()(I x, difference_type_t<I> n) const;

Effects: Equivalent to: advance(x, n); return x;

template <Iterator I, Sentinel<I> S> constexpr I operator()(I x, S bound) const;

Effects: Equivalent to: advance(x, bound); return x;

template <Iterator I, Sentinel<I> S> constexpr I operator()(I x, difference_type_t<I> n, S bound) const;

Effects: Equivalent to: advance(x, n, bound); return x;

The name prev denotes a customization point object. It has the following function call operators:

template <BidirectionalIterator I> constexpr I operator()(I x) const;

Effects: Equivalent to: --x; return x;

template <BidirectionalIterator I> constexpr I operator()(I x, difference_type_t<I> n) const;

Effects: Equivalent to: advance(x, -n); return x;

template <BidirectionalIterator I> constexpr I operator()(I x, difference_type_t<I> n, I bound) const;

Effects: Equivalent to: advance(x, -n, bound); return x;