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);
};
```

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

: *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, repeated calls
might not return equal values or might not be well-defined;
ranges::begin should be called at most once for such a range.

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

```
template<class>
inline constexpr bool enable_safe_range = false;
```

Remarks:
Pursuant to [namespace.std], users may specialize enable_safe_range
for cv-unqualified program-defined types.

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

[ Example

: *end example*

]Each specialization S of class template subrange ([range.subrange])
models safe_range because

β - enable_safe_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.