From Jason Turner

[range.req]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmprdg13tdx/{from.md → to.md} +260 -0
tmp/tmprdg13tdx/{from.md → to.md} RENAMED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Range requirements <a id="range.req">[[range.req]]</a>
2
+
3
+ ### General <a id="range.req.general">[[range.req.general]]</a>
4
+
5
+ Ranges are an abstraction that allow a C++ program to operate on
6
+ elements of data structures uniformly. Calling `ranges::begin` on a
7
+ range returns an object whose type models `input_or_output_iterator`
8
+ [[iterator.concept.iterator]]. Calling `ranges::end` on a range returns
9
+ an object whose type `S`, together with the type `I` of the object
10
+ returned by `ranges::begin`, models `sentinel_for<S, I>`. The library
11
+ formalizes the interfaces, semantics, and complexity of ranges to enable
12
+ algorithms and range adaptors that work efficiently on different types
13
+ of sequences.
14
+
15
+ The `range` concept requires that `ranges::begin` and `ranges::end`
16
+ return an iterator and a sentinel, respectively. The `sized_range`
17
+ concept refines `range` with the requirement that `ranges::size` be
18
+ amortized 𝑂(1). The `view` concept specifies requirements on a `range`
19
+ type with constant-time destruction and move operations.
20
+
21
+ Several refinements of `range` group requirements that arise frequently
22
+ in concepts and algorithms. Common ranges are ranges for which
23
+ `ranges::begin` and `ranges::end` return objects of the same type.
24
+ Random access ranges are ranges for which `ranges::begin` returns a type
25
+ that models `random_access_iterator` [[iterator.concept.random.access]].
26
+ (Contiguous, bidirectional, forward, input, and output ranges are
27
+ defined similarly.) Viewable ranges can be converted to views.
28
+
29
+ ### Ranges <a id="range.range">[[range.range]]</a>
30
+
31
+ The `range` concept defines the requirements of a type that allows
32
+ iteration over its elements by providing an iterator and sentinel that
33
+ denote the elements of the range.
34
+
35
+ ``` cpp
36
+ template<class T>
37
+ concept range =
38
+ requires(T& t) {
39
+ ranges::begin(t); // sometimes equality-preserving (see below)
40
+ ranges::end(t);
41
+ };
42
+ ```
43
+
44
+ The required expressions `ranges::begin(t)` and `ranges::end(t)` of the
45
+ `range` concept do not require implicit expression
46
+ variations [[concepts.equality]].
47
+
48
+ Given an expression `t` such that `decltype((t))` is `T&`, `T` models
49
+ `range` only if
50
+
51
+ - \[`ranges::begin(t)`, `ranges::end(t)`) denotes a
52
+ range [[iterator.requirements.general]],
53
+ - both `ranges::begin(t)` and `ranges::end(t)` are amortized constant
54
+ time and non-modifying, and
55
+ - if the type of `ranges::begin(t)` models `forward_iterator`,
56
+ `ranges::begin(t)` is equality-preserving.
57
+
58
+ [*Note 1*: Equality preservation of both `ranges::begin` and
59
+ `ranges::end` enables passing a `range` whose iterator type models
60
+ `forward_iterator` to multiple algorithms and making multiple passes
61
+ over the range by repeated calls to `ranges::begin` and `ranges::end`.
62
+ Since `ranges::begin` is not required to be equality-preserving when the
63
+ return type does not model `forward_iterator`, repeated calls might not
64
+ return equal values or might not be well-defined; `ranges::begin` should
65
+ be called at most once for such a range. — *end note*]
66
+
67
+ ``` cpp
68
+ template<class T>
69
+ concept borrowed_range =
70
+ range<T> &&
71
+ (is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>);
72
+ ```
73
+
74
+ Given an expression `E` such that `decltype((E))` is `T`, `T` models
75
+ `borrowed_range` only if the validity of iterators obtained from the
76
+ object denoted by `E` is not tied to the lifetime of that object.
77
+
78
+ [*Note 2*: Since the validity of iterators is not tied to the lifetime
79
+ of an object whose type models `borrowed_range`, a function can accept
80
+ arguments of such a type by value and return iterators obtained from it
81
+ without danger of dangling. — *end note*]
82
+
83
+ ``` cpp
84
+ template<class>
85
+ inline constexpr bool enable_borrowed_range = false;
86
+ ```
87
+
88
+ *Remarks:* Pursuant to [[namespace.std]], users may specialize
89
+ `enable_borrowed_range` for cv-unqualified program-defined types. Such
90
+ specializations shall be usable in constant expressions [[expr.const]]
91
+ and have type `const bool`.
92
+
93
+ [*Example 1*:
94
+
95
+ Each specialization `S` of class template `subrange` [[range.subrange]]
96
+ models `borrowed_range` because
97
+
98
+ - `enable_borrowed_range<S>` is specialized to have the value `true`,
99
+ and
100
+ - `S`’s iterators do not have validity tied to the lifetime of an `S`
101
+ object because they are “borrowed” from some other range.
102
+
103
+ — *end example*]
104
+
105
+ ### Sized ranges <a id="range.sized">[[range.sized]]</a>
106
+
107
+ The `sized_range` concept refines `range` with the requirement that the
108
+ number of elements in the range can be determined in amortized constant
109
+ time using `ranges::size`.
110
+
111
+ ``` cpp
112
+ template<class T>
113
+ concept sized_range =
114
+ range<T> &&
115
+ requires(T& t) { ranges::size(t); };
116
+ ```
117
+
118
+ Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
119
+ `sized_range` only if
120
+
121
+ - `ranges::size(t)` is amortized 𝑂(1), does not modify `t`, and is equal
122
+ to `ranges::distance(t)`, and
123
+ - if `iterator_t<T>` models `forward_iterator`, `ranges::size(t)` is
124
+ well-defined regardless of the evaluation of `ranges::begin(t)`.
125
+ \[*Note 1*: `ranges::size(t)` is otherwise not required to be
126
+ well-defined after evaluating `ranges::begin(t)`. For example,
127
+ `ranges::size(t)` might be well-defined for a `sized_range` whose
128
+ iterator type does not model `forward_iterator` only if evaluated
129
+ before the first call to `ranges::begin(t)`. — *end note*]
130
+
131
+ ``` cpp
132
+ template<class>
133
+ inline constexpr bool disable_sized_range = false;
134
+ ```
135
+
136
+ *Remarks:* Pursuant to [[namespace.std]], users may specialize
137
+ `disable_sized_range` for cv-unqualified program-defined types. Such
138
+ specializations shall be usable in constant expressions [[expr.const]]
139
+ and have type `const bool`.
140
+
141
+ [*Note 1*: `disable_sized_range` allows use of range types with the
142
+ library that satisfy but do not in fact model
143
+ `sized_range`. — *end note*]
144
+
145
+ ### Views <a id="range.view">[[range.view]]</a>
146
+
147
+ The `view` concept specifies the requirements of a `range` type that has
148
+ constant time move construction, move assignment, and destruction; that
149
+ is, the cost of these operations is independent of the number of
150
+ elements in the `view`.
151
+
152
+ ``` cpp
153
+ template<class T>
154
+ concept view =
155
+ range<T> && movable<T> && default_initializable<T> && enable_view<T>;
156
+ ```
157
+
158
+ `T` models `view` only if:
159
+
160
+ - `T` has 𝑂(1) move construction; and
161
+ - `T` has 𝑂(1) move assignment; and
162
+ - `T` has 𝑂(1) destruction; and
163
+ - `copy_constructible<T>` is `false`, or `T` has 𝑂(1) copy construction;
164
+ and
165
+ - `copyable<T>` is `false`, or `T` has 𝑂(1) copy assignment.
166
+
167
+ [*Example 1*:
168
+
169
+ Examples of `view`s are:
170
+
171
+ - A `range` type that wraps a pair of iterators.
172
+ - A `range` type that holds its elements by `shared_ptr` and shares
173
+ ownership with all its copies.
174
+ - A `range` type that generates its elements on demand.
175
+
176
+ Most containers [[containers]] are not views since destruction of the
177
+ container destroys the elements, which cannot be done in constant time.
178
+
179
+ — *end example*]
180
+
181
+ Since the difference between `range` and `view` is largely semantic, the
182
+ two are differentiated with the help of `enable_view`.
183
+
184
+ ``` cpp
185
+ template<class T>
186
+ inline constexpr bool enable_view = derived_from<T, view_base>;
187
+ ```
188
+
189
+ *Remarks:* Pursuant to [[namespace.std]], users may specialize
190
+ `enable_view` to `true` for cv-unqualified program-defined types which
191
+ model `view`, and `false` for types which do not. Such specializations
192
+ shall be usable in constant expressions [[expr.const]] and have type
193
+ `const bool`.
194
+
195
+ ### Other range refinements <a id="range.refinements">[[range.refinements]]</a>
196
+
197
+ The `output_range` concept specifies requirements of a `range` type for
198
+ which `ranges::begin` returns a model of `output_iterator`
199
+ [[iterator.concept.output]]. `input_range`, `forward_range`,
200
+ `bidirectional_range`, and `random_access_range` are defined similarly.
201
+
202
+ ``` cpp
203
+ template<class R, class T>
204
+ concept output_range =
205
+ range<R> && output_iterator<iterator_t<R>, T>;
206
+
207
+ template<class T>
208
+ concept input_range =
209
+ range<T> && input_iterator<iterator_t<T>>;
210
+
211
+ template<class T>
212
+ concept forward_range =
213
+ input_range<T> && forward_iterator<iterator_t<T>>;
214
+
215
+ template<class T>
216
+ concept bidirectional_range =
217
+ forward_range<T> && bidirectional_iterator<iterator_t<T>>;
218
+
219
+ template<class T>
220
+ concept random_access_range =
221
+ bidirectional_range<T> && random_access_iterator<iterator_t<T>>;
222
+ ```
223
+
224
+ `contiguous_range` additionally requires that the `ranges::data`
225
+ customization point [[range.prim.data]] is usable with the range.
226
+
227
+ ``` cpp
228
+ template<class T>
229
+ concept contiguous_range =
230
+ random_access_range<T> && contiguous_iterator<iterator_t<T>> &&
231
+ requires(T& t) {
232
+ { ranges::data(t) } -> same_as<add_pointer_t<range_reference_t<T>>>;
233
+ };
234
+ ```
235
+
236
+ Given an expression `t` such that `decltype((t))` is `T&`, `T` models
237
+ `contiguous_range` only if
238
+ `to_address({}ranges::begin(t)) == ranges::data(t)` is `true`.
239
+
240
+ The `common_range` concept specifies requirements of a `range` type for
241
+ which `ranges::begin` and `ranges::end` return objects of the same type.
242
+
243
+ [*Example 1*: The standard containers [[containers]] model
244
+ `common_range`. — *end example*]
245
+
246
+ ``` cpp
247
+ template<class T>
248
+ concept common_range =
249
+ range<T> && same_as<iterator_t<T>, sentinel_t<T>>;
250
+ ```
251
+
252
+ The `viewable_range` concept specifies the requirements of a `range`
253
+ type that can be converted to a `view` safely.
254
+
255
+ ``` cpp
256
+ template<class T>
257
+ concept viewable_range =
258
+ range<T> && (borrowed_range<T> || view<remove_cvref_t<T>>);
259
+ ```
260
+