129 lines
4.7 KiB
Markdown
129 lines
4.7 KiB
Markdown
[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*]
|