[range.range]

# 25 Ranges library [[ranges]](./#ranges)

## 25.4 Range requirements [[range.req]](range.req#range.range)

### 25.4.2 Ranges [range.range]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1323)

The [range](#concept:range "25.4.2 Ranges [range.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[.](#1.sentence-1)

[ð](#concept: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);
    };
`

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1338)

Given an expression t such that decltype((t)) is T&,T models [range](#concept:range "25.4.2 Ranges [range.range]") only if

- [(2.1)](#2.1)

[ranges​::​begin(t), ranges​::​end(t))
 denotes a range ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")),

- [(2.2)](#2.2)

bothranges​::​begin(t) andranges​::​end(t) are amortized constant time and non-modifying, and

- [(2.3)](#2.3)

if the type of ranges​::​begin(t) models[forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]"), ranges​::​begin(t) is equality-preserving[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1355)

[*Note [1](#note-1)*:

Equality preservation of both ranges​::​begin andranges​::​end enables passing a range whose iterator
type models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]") to multiple
algorithms and making multiple passes over the range by repeated calls toranges​::​begin and ranges​::​end[.](#3.sentence-1)

Since ranges​::​begin is not required to be equality-preserving
when the return type does not model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]"),
it is possible for repeated calls
to not return equal values or to not be well-defined[.](#3.sentence-2)

â *end note*]

[ð](#concept:borrowed_range)

`template<class T>
  concept [borrowed_range](#concept:borrowed_range "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>>);
`

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1376)

Let U be remove_reference_t<T> if T is an rvalue reference type, and T otherwise[.](#4.sentence-1)

Given a variable u of type U,T models [borrowed_range](#concept:borrowed_range "25.4.2 Ranges [range.range]") only if
the validity of iterators obtained from u is not tied to the lifetime of that variable[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1384)

[*Note [2](#note-2)*:

Since the validity of iterators is not tied to the lifetime of
a variable whose type models [borrowed_range](#concept:borrowed_range "25.4.2 Ranges [range.range]"),
a function with a parameter of such a type can
return iterators obtained from it without danger of dangling[.](#5.sentence-1)

â *end note*]

[ð](#lib:enable_borrowed_range)

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

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1400)

*Remarks*: Pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"), users may specialize enable_borrowed_range for cv-unqualified program-defined types[.](#6.sentence-1)

Such specializations shall be
usable in constant expressions ([[expr.const]](expr.const "7.7 Constant expressions")) and
have type const bool[.](#6.sentence-2)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1408)

[*Example [1](#example-1)*:

Each specialization S of class template subrange ([[range.subrange]](range.subrange "25.5.4 Sub-ranges"))
models [borrowed_range](#concept:borrowed_range "25.4.2 Ranges [range.range]") because

- [(7.1)](#7.1)

enable_borrowed_range<S> is specialized
to have the value true, and

- [(7.2)](#7.2)

S's iterators
do not have validity tied to the lifetime of an S object
because they are âborrowedâ from some other range[.](#7.sentence-1)

â *end example*]
