[range.range] (original) (raw)
25 Ranges library [ranges]
25.4 Range requirements [range.req]
25.4.2 Ranges [range.range]
The range concept defines the requirements of a type that allows iteration over its elements by providing an iterator and sentinel that denote the elements of the range.
template<class T> concept [range](#concept:range "25.4.2 Ranges [range.range]") = requires(T& t) { ranges::begin(t); // sometimes equality-preserving (see below) ranges::end(t);};
Given an expression t such that decltype((t)) is T&,T models range only if
- [ranges::begin(t), ranges::end(t)) denotes a range ([iterator.requirements.general]),
- bothranges::begin(t)andranges::end(t)are amortized constant time and non-modifying, and
- if the type of ranges::begin(t) modelsforward_iterator, ranges::begin(t) is equality-preserving.
[Note 1:
Equality preservation of both ranges::begin andranges::end enables passing a range whose iterator type models forward_iterator to multiple algorithms and making multiple passes over the range by repeated calls toranges::begin and ranges::end.
Since ranges::begin is not required to be equality-preserving when the return type does not model forward_iterator, it is possible for repeated calls to not return equal values or to not be well-defined.
— _end note_]
template<class T> concept [borrowed_range](#concept:borrowed%5Frange "25.4.2 Ranges [range.range]") = [range](#concept:range "25.4.2 Ranges [range.range]")<T> && (is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>);
Let U be remove_reference_t<T>if T is an rvalue reference type, and T otherwise.
Given a variable u of type U,T models borrowed_range only if the validity of iterators obtained from uis not tied to the lifetime of that variable.
[Note 2:
Since the validity of iterators is not tied to the lifetime of a variable whose type models borrowed_range, a function with a parameter of such a type can return iterators obtained from it without danger of dangling.
— _end note_]
template<class> constexpr bool enable_borrowed_range = false;
Remarks: Pursuant to [namespace.std], users may specialize enable_borrowed_rangefor cv-unqualified program-defined types.
Such specializations shall be usable in constant expressions ([expr.const]) and have type const bool.
[Example 1:
Each specialization S of class template subrange ([range.subrange]) models borrowed_range because
- enable_borrowed_range<S> is specialized to have the value true, and
- S's iterators do not have validity tied to the lifetime of an S object because they are “borrowed” from some other range.
— _end example_]