The required expressions
ranges::begin(t)
and
ranges::end(t)
of the range concept
do not require implicit expression variations ([concepts.equality]).

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*: *end note*]

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.

β ```
template<class T>
concept borrowed_range =
range<T> && (is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>);
```

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*: *end note*]

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.

β ```
template<class>
inline constexpr bool enable_borrowed_range = false;
```

Such specializations shall be
usable in constant expressions ([expr.const]) and
have type const bool.

[*Example 1*: *end example*]

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.