26 Ranges library [ranges]

26.4 Range requirements [range.req]

26.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 = 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]),
  • both ranges​::​begin(t) and ranges​::​end(t) are amortized constant time and non-modifying, and
  • if the type of ranges​::​begin(t) models forward_iterator, ranges​::​begin(t) is equality-preserving.
[Note 1: 
Equality preservation of both ranges​::​begin and ranges​::​end enables passing a range whose iterator type models forward_iterator to multiple algorithms and making multiple passes over the range by repeated calls to ranges​::​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 = 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 u is 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_range for 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]