From Jason Turner

[range.req]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpgcsmfwjj/{from.md → to.md} +71 -37
tmp/tmpgcsmfwjj/{from.md → to.md} RENAMED
@@ -1,10 +1,10 @@
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
@@ -14,11 +14,11 @@ 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
@@ -54,37 +54,37 @@ Given an expression `t` such that `decltype((t))` is `T&`, `T` models
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]]
@@ -109,30 +109,29 @@ 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]]
@@ -143,51 +142,66 @@ 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`.
@@ -220,11 +234,11 @@ 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>> &&
@@ -247,14 +261,34 @@ which `ranges::begin` and `ranges::end` return objects of the same type.
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
 
 
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 allows 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
 
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 to provide operations with predictable complexity.
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
 
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`, it is possible for
64
+ repeated calls to not return equal values or to not be
65
+ well-defined. — *end note*]
66
 
67
  ``` cpp
68
  template<class T>
69
  concept borrowed_range =
70
+ range<T> && (is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>);
 
71
  ```
72
 
73
+ Let `U` be `remove_reference_t<T>` if `T` is an rvalue reference type,
74
+ and `T` otherwise. Given a variable `u` of type `U`, `T` models
75
+ `borrowed_range` only if the validity of iterators obtained from `u` is
76
+ not tied to the lifetime of that variable.
77
 
78
  [*Note 2*: Since the validity of iterators is not tied to the lifetime
79
+ of a variable whose type models `borrowed_range`, a function with a
80
+ parameter of such a type can return iterators obtained from it without
81
+ danger of dangling. — *end note*]
82
 
83
  ``` cpp
84
  template<class>
85
+ 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]]
 
109
  time using `ranges::size`.
110
 
111
  ``` cpp
112
  template<class T>
113
  concept sized_range =
114
+ range<T> && requires(T& t) { ranges::size(t); };
 
115
  ```
116
 
117
  Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
118
  `sized_range` only if
119
 
120
  - `ranges::size(t)` is amortized 𝑂(1), does not modify `t`, and is equal
121
+ to `ranges::distance(ranges::begin(t), ranges::end(t))`, and
122
  - if `iterator_t<T>` models `forward_iterator`, `ranges::size(t)` is
123
  well-defined regardless of the evaluation of `ranges::begin(t)`.
124
  \[*Note 1*: `ranges::size(t)` is otherwise not required to be
125
+ well-defined after evaluating `ranges::begin(t)`. For example, it is
126
+ possible for `ranges::size(t)` to be well-defined for a `sized_range`
127
+ whose iterator type does not model `forward_iterator` only if
128
+ evaluated before the first call to `ranges::begin(t)`. — *end note*]
129
 
130
  ``` cpp
131
  template<class>
132
+ constexpr bool disable_sized_range = false;
133
  ```
134
 
135
  *Remarks:* Pursuant to [[namespace.std]], users may specialize
136
  `disable_sized_range` for cv-unqualified program-defined types. Such
137
  specializations shall be usable in constant expressions [[expr.const]]
 
142
  `sized_range`. — *end note*]
143
 
144
  ### Views <a id="range.view">[[range.view]]</a>
145
 
146
  The `view` concept specifies the requirements of a `range` type that has
147
+ the semantic properties below, which make it suitable for use in
148
+ constructing range adaptor pipelines [[range.adaptors]].
 
149
 
150
  ``` cpp
151
  template<class T>
152
  concept view =
153
+ range<T> && movable<T> && enable_view<T>;
154
  ```
155
 
156
  `T` models `view` only if:
157
 
158
  - `T` has 𝑂(1) move construction; and
159
+ - move assignment of an object of type `T` is no more complex than
160
+ destruction followed by move construction; and
161
+ - if N copies and/or moves are made from an object of type `T` that
162
+ contained M elements, then those N objects have 𝑂(N+M) destruction;
163
+ and
164
  - `copy_constructible<T>` is `false`, or `T` has 𝑂(1) copy construction;
165
  and
166
+ - `copyable<T>` is `false`, or copy assignment of an object of type `T`
167
+ is no more complex than destruction followed by copy construction.
168
+
169
+ [*Note 1*: The constraints on copying and moving imply that a
170
+ moved-from object of type `T` has 𝑂(1) destruction. — *end note*]
171
 
172
  [*Example 1*:
173
 
174
+ Examples of views are:
175
 
176
  - A `range` type that wraps a pair of iterators.
177
  - A `range` type that holds its elements by `shared_ptr` and shares
178
  ownership with all its copies.
179
  - A `range` type that generates its elements on demand.
180
 
181
+ A container such as `vector<string>` does not meet the semantic
182
+ requirements of `view` since copying the container copies all of the
183
+ elements, which cannot be done in constant time.
184
 
185
  — *end example*]
186
 
187
  Since the difference between `range` and `view` is largely semantic, the
188
  two are differentiated with the help of `enable_view`.
189
 
190
  ``` cpp
191
  template<class T>
192
+ constexpr bool is-derived-from-view-interface = see belownc; // exposition only
193
+ template<class T>
194
+ constexpr bool enable_view =
195
+ derived_from<T, view_base> || is-derived-from-view-interface<T>;
196
  ```
197
 
198
+ For a type `T`, *`is-derived-from-view-interface`*`<T>` is `true` if and
199
+ only if `T` has exactly one public base class `view_interface<U>` for
200
+ some type `U` and `T` has no base classes of type `view_interface<V>`
201
+ for any other type `V`.
202
+
203
  *Remarks:* Pursuant to [[namespace.std]], users may specialize
204
  `enable_view` to `true` for cv-unqualified program-defined types which
205
  model `view`, and `false` for types which do not. Such specializations
206
  shall be usable in constant expressions [[expr.const]] and have type
207
  `const bool`.
 
234
  concept random_access_range =
235
  bidirectional_range<T> && random_access_iterator<iterator_t<T>>;
236
  ```
237
 
238
  `contiguous_range` additionally requires that the `ranges::data`
239
+ customization point object [[range.prim.data]] is usable with the range.
240
 
241
  ``` cpp
242
  template<class T>
243
  concept contiguous_range =
244
  random_access_range<T> && contiguous_iterator<iterator_t<T>> &&
 
261
  template<class T>
262
  concept common_range =
263
  range<T> && same_as<iterator_t<T>, sentinel_t<T>>;
264
  ```
265
 
266
+ ``` cpp
267
+ template<class R>
268
+ constexpr bool is-initializer-list = see below; // exposition only
269
+ ```
270
+
271
+ For a type `R`, *`is-initializer-list`*`<R>` is `true` if and only if
272
+ `remove_cvref_t<R>` is a specialization of `initializer_list`.
273
+
274
  The `viewable_range` concept specifies the requirements of a `range`
275
+ type that can be converted to a view safely.
276
 
277
  ``` cpp
278
  template<class T>
279
  concept viewable_range =
280
+ range<T> &&
281
+ ((view<remove_cvref_t<T>> && constructible_from<remove_cvref_t<T>, T>) ||
282
+ (!view<remove_cvref_t<T>> &&
283
+ (is_lvalue_reference_v<T> || (movable<remove_reference_t<T>> && !is-initializer-list<T>))));
284
+ ```
285
+
286
+ The `constant_range` concept specifies the requirements of a `range`
287
+ type whose elements are not modifiable.
288
+
289
+ ``` cpp
290
+ template<class T>
291
+ concept constant_range =
292
+ input_range<T> && constant-iterator<iterator_t<T>>;
293
  ```
294