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