From Jason Turner

[range.factories]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp39f0s42m/{from.md → to.md} +812 -0
tmp/tmp39f0s42m/{from.md → to.md} RENAMED
@@ -0,0 +1,812 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Range factories <a id="range.factories">[[range.factories]]</a>
2
+
3
+ This subclause defines *range factories*, which are utilities to create
4
+ a `view`.
5
+
6
+ Range factories are declared in namespace `std::ranges::views`.
7
+
8
+ ### Empty view <a id="range.empty">[[range.empty]]</a>
9
+
10
+ #### Overview <a id="range.empty.overview">[[range.empty.overview]]</a>
11
+
12
+ `empty_view` produces a `view` of no elements of a particular type.
13
+
14
+ [*Example 1*:
15
+
16
+ ``` cpp
17
+ empty_view<int> e;
18
+ static_assert(ranges::empty(e));
19
+ static_assert(0 == e.size());
20
+ ```
21
+
22
+ — *end example*]
23
+
24
+ #### Class template `empty_view` <a id="range.empty.view">[[range.empty.view]]</a>
25
+
26
+ ``` cpp
27
+ namespace std::ranges {
28
+ template<class T>
29
+ requires is_object_v<T>
30
+ class empty_view : public view_interface<empty_view<T>> {
31
+ public:
32
+ static constexpr T* begin() noexcept { return nullptr; }
33
+ static constexpr T* end() noexcept { return nullptr; }
34
+ static constexpr T* data() noexcept { return nullptr; }
35
+ static constexpr size_t size() noexcept { return 0; }
36
+ static constexpr bool empty() noexcept { return true; }
37
+ };
38
+ }
39
+ ```
40
+
41
+ ### Single view <a id="range.single">[[range.single]]</a>
42
+
43
+ #### Overview <a id="range.single.overview">[[range.single.overview]]</a>
44
+
45
+ `single_view` produces a `view` that contains exactly one element of a
46
+ specified value.
47
+
48
+ The name `views::single` denotes a customization point object
49
+ [[customization.point.object]]. Given a subexpression `E`, the
50
+ expression `views::single(E)` is expression-equivalent to
51
+ `single_view{E}`.
52
+
53
+ [*Example 1*:
54
+
55
+ ``` cpp
56
+ single_view s{4};
57
+ for (int i : s)
58
+ cout << i; // prints 4
59
+ ```
60
+
61
+ — *end example*]
62
+
63
+ #### Class template `single_view` <a id="range.single.view">[[range.single.view]]</a>
64
+
65
+ ``` cpp
66
+ namespace std::ranges {
67
+ template<copy_constructible T>
68
+ requires is_object_v<T>
69
+ class single_view : public view_interface<single_view<T>> {
70
+ private:
71
+ semiregular-box<T> value_; // exposition only{} (see [range.semi.wrap])
72
+ public:
73
+ single_view() = default;
74
+ constexpr explicit single_view(const T& t);
75
+ constexpr explicit single_view(T&& t);
76
+ template<class... Args>
77
+ requires constructible_from<T, Args...>
78
+ constexpr single_view(in_place_t, Args&&... args);
79
+
80
+ constexpr T* begin() noexcept;
81
+ constexpr const T* begin() const noexcept;
82
+ constexpr T* end() noexcept;
83
+ constexpr const T* end() const noexcept;
84
+ static constexpr size_t size() noexcept;
85
+ constexpr T* data() noexcept;
86
+ constexpr const T* data() const noexcept;
87
+ };
88
+ }
89
+ ```
90
+
91
+ ``` cpp
92
+ constexpr explicit single_view(const T& t);
93
+ ```
94
+
95
+ *Effects:* Initializes *value\_* with `t`.
96
+
97
+ ``` cpp
98
+ constexpr explicit single_view(T&& t);
99
+ ```
100
+
101
+ *Effects:* Initializes *value\_* with `std::move(t)`.
102
+
103
+ ``` cpp
104
+ template<class... Args>
105
+ constexpr single_view(in_place_t, Args&&... args);
106
+ ```
107
+
108
+ *Effects:* Initializes *value\_* as if by
109
+ *`value_`*`{in_place, std::forward<Args>(args)...}`.
110
+
111
+ ``` cpp
112
+ constexpr T* begin() noexcept;
113
+ constexpr const T* begin() const noexcept;
114
+ ```
115
+
116
+ *Effects:* Equivalent to: `return data();`
117
+
118
+ ``` cpp
119
+ constexpr T* end() noexcept;
120
+ constexpr const T* end() const noexcept;
121
+ ```
122
+
123
+ *Effects:* Equivalent to: `return data() + 1;`
124
+
125
+ ``` cpp
126
+ static constexpr size_t size() noexcept;
127
+ ```
128
+
129
+ *Effects:* Equivalent to: `return 1;`
130
+
131
+ ``` cpp
132
+ constexpr T* data() noexcept;
133
+ constexpr const T* data() const noexcept;
134
+ ```
135
+
136
+ *Effects:* Equivalent to: `return `*`value_`*`.operator->();`
137
+
138
+ ### Iota view <a id="range.iota">[[range.iota]]</a>
139
+
140
+ #### Overview <a id="range.iota.overview">[[range.iota.overview]]</a>
141
+
142
+ `iota_view` generates a sequence of elements by repeatedly incrementing
143
+ an initial value.
144
+
145
+ The name `views::iota` denotes a customization point object
146
+ [[customization.point.object]]. Given subexpressions `E` and `F`, the
147
+ expressions `views::iota(E)` and `views::iota(E, F)` are
148
+ expression-equivalent to `iota_view{E}` and `iota_view{E, F}`,
149
+ respectively.
150
+
151
+ [*Example 1*:
152
+
153
+ ``` cpp
154
+ for (int i : iota_view{1, 10})
155
+ cout << i << ' '; // prints: 1 2 3 4 5 6 7 8 9
156
+ ```
157
+
158
+ — *end example*]
159
+
160
+ #### Class template `iota_view` <a id="range.iota.view">[[range.iota.view]]</a>
161
+
162
+ ``` cpp
163
+ namespace std::ranges {
164
+ template<class I>
165
+ concept decrementable = // exposition only
166
+ see below;
167
+ template<class I>
168
+ concept advanceable = // exposition only
169
+ see below;
170
+
171
+ template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
172
+ requires weakly-equality-comparable-with<W, Bound> && semiregular<W>
173
+ class iota_view : public view_interface<iota_view<W, Bound>> {
174
+ private:
175
+ // [range.iota.iterator], class iota_view::iterator
176
+ struct iterator; // exposition only
177
+ // [range.iota.sentinel], class iota_view::sentinel
178
+ struct sentinel; // exposition only
179
+ W value_ = W(); // exposition only
180
+ Bound bound_ = Bound(); // exposition only
181
+ public:
182
+ iota_view() = default;
183
+ constexpr explicit iota_view(W value);
184
+ constexpr iota_view(type_identity_t<W> value,
185
+ type_identity_t<Bound> bound);
186
+ constexpr iota_view(iterator first, sentinel last) : iota_view(*first, last.bound_) {}
187
+
188
+ constexpr iterator begin() const;
189
+ constexpr auto end() const;
190
+ constexpr iterator end() const requires same_as<W, Bound>;
191
+
192
+ constexpr auto size() const requires see below;
193
+ };
194
+
195
+ template<class W, class Bound>
196
+ requires (!is-integer-like<W> || !is-integer-like<Bound> ||
197
+ (is-signed-integer-like<W> == is-signed-integer-like<Bound>))
198
+ iota_view(W, Bound) -> iota_view<W, Bound>;
199
+ }
200
+ ```
201
+
202
+ Let `IOTA-DIFF-T(W)` be defined as follows:
203
+
204
+ - If `W` is not an integral type, or if it is an integral type and
205
+ `sizeof(iter_difference_t<W>)` is greater than `sizeof(W)`, then
206
+ `IOTA-DIFF-T(W)` denotes `iter_difference_t<W>`.
207
+ - Otherwise, `IOTA-DIFF-T(W)` is a signed integer type of width greater
208
+ than the width of `W` if such a type exists.
209
+ - Otherwise, `IOTA-DIFF-T(W)` is an unspecified signed-integer-like type
210
+ [[iterator.concept.winc]] of width not less than the width of `W`.
211
+ \[*Note 1*: It is unspecified whether this type satisfies
212
+ `weakly_incrementable`. — *end note*]
213
+
214
+ The exposition-only *decrementable* concept is equivalent to:
215
+
216
+ ``` cpp
217
+ template<class I>
218
+ concept decrementable =
219
+ incrementable<I> && requires(I i) {
220
+ { --i } -> same_as<I&>;
221
+ { i-- } -> same_as<I>;
222
+ };
223
+ ```
224
+
225
+ When an object is in the domain of both pre- and post-decrement, the
226
+ object is said to be *decrementable*.
227
+
228
+ Let `a` and `b` be equal objects of type `I`. `I` models `decrementable`
229
+ only if
230
+
231
+ - If `a` and `b` are decrementable, then the following are all true:
232
+ - `addressof(–a) == addressof(a)`
233
+ - `bool(a– == b)`
234
+ - `bool(((void)a–, a) == –b)`
235
+ - `bool(++(–a) == b)`.
236
+ - If `a` and `b` are incrementable, then `bool(–(++a) == b)`.
237
+
238
+ The exposition-only *advanceable* concept is equivalent to:
239
+
240
+ ``` cpp
241
+ template<class I>
242
+ concept advanceable =
243
+ decrementable<I> && totally_ordered<I> &&
244
+ requires(I i, const I j, const IOTA-DIFF-T(I) n) {
245
+ { i += n } -> same_as<I&>;
246
+ { i -= n } -> same_as<I&>;
247
+ I(j + n);
248
+ I(n + j);
249
+ I(j - n);
250
+ { j - j } -> convertible_to<IOTA-DIFF-T(I)>;
251
+ };
252
+ ```
253
+
254
+ Let `D` be `IOTA-DIFF-T(I)`. Let `a` and `b` be objects of type `I` such
255
+ that `b` is reachable from `a` after `n` applications of `++a`, for some
256
+ value `n` of type `D`. `I` models `advanceable` only if
257
+
258
+ - `(a += n)` is equal to `b`.
259
+ - `addressof(a += n)` is equal to `addressof(a)`.
260
+ - `I(a + n)` is equal to `(a += n)`.
261
+ - For any two positive values `x` and `y` of type `D`, if
262
+ `I(a + D(x + y))` is well-defined, then `I(a + D(x + y))` is equal to
263
+ `I(I(a + x) + y)`.
264
+ - `I(a + D(0))` is equal to `a`.
265
+ - If `I(a + D(n - 1))` is well-defined, then `I(a + n)` is equal to
266
+ `[](I c) { return ++c; }(I(a + D(n - 1)))`.
267
+ - `(b += -n)` is equal to `a`.
268
+ - `(b -= n)` is equal to `a`.
269
+ - `addressof(b -= n)` is equal to `addressof(b)`.
270
+ - `I(b - n)` is equal to `(b -= n)`.
271
+ - `D(b - a)` is equal to `n`.
272
+ - `D(a - b)` is equal to `D(-n)`.
273
+ - `bool(a <= b)` is `true`.
274
+
275
+ ``` cpp
276
+ constexpr explicit iota_view(W value);
277
+ ```
278
+
279
+ *Preconditions:* `Bound` denotes `unreachable_sentinel_t` or `Bound()`
280
+ is reachable from `value`.
281
+
282
+ *Effects:* Initializes *value\_* with `value`.
283
+
284
+ ``` cpp
285
+ constexpr iota_view(type_identity_t<W> value, type_identity_t<Bound> bound);
286
+ ```
287
+
288
+ *Preconditions:* `Bound` denotes `unreachable_sentinel_t` or `bound` is
289
+ reachable from `value`. When `W` and `Bound` model
290
+ `totally_ordered_with`, then `bool(value <= bound)` is `true`.
291
+
292
+ *Effects:* Initializes *value\_* with `value` and *bound\_* with
293
+ `bound`.
294
+
295
+ ``` cpp
296
+ constexpr iterator begin() const;
297
+ ```
298
+
299
+ *Effects:* Equivalent to: `return iterator{`*`value_`*`};`
300
+
301
+ ``` cpp
302
+ constexpr auto end() const;
303
+ ```
304
+
305
+ *Effects:* Equivalent to:
306
+
307
+ ``` cpp
308
+ if constexpr (same_as<Bound, unreachable_sentinel_t>)
309
+ return unreachable_sentinel;
310
+ else
311
+ return sentinel{bound_};
312
+ ```
313
+
314
+ ``` cpp
315
+ constexpr iterator end() const requires same_as<W, Bound>;
316
+ ```
317
+
318
+ *Effects:* Equivalent to: `return iterator{bound_};`
319
+
320
+ ``` cpp
321
+ constexpr auto size() const requires see below;
322
+ ```
323
+
324
+ *Effects:* Equivalent to:
325
+
326
+ ``` cpp
327
+ if constexpr (is-integer-like<W> && is-integer-like<Bound>)
328
+ return (value_ < 0)
329
+ ? ((bound_ < 0)
330
+ ? to-unsigned-like(-value_) - to-unsigned-like(-bound_)
331
+ : to-unsigned-like(bound_) + to-unsigned-like(-value_))
332
+ : to-unsigned-like(bound_) - to-unsigned-like(value_);
333
+ else
334
+ return to-unsigned-like(bound_ - value_);
335
+ ```
336
+
337
+ *Remarks:* The expression in the *requires-clause* is equivalent to
338
+
339
+ ``` cpp
340
+ (same_as<W, Bound> && advanceable<W>) || (integral<W> && integral<Bound>) ||
341
+ sized_sentinel_for<Bound, W>
342
+ ```
343
+
344
+ #### Class `iota_view::iterator` <a id="range.iota.iterator">[[range.iota.iterator]]</a>
345
+
346
+ ``` cpp
347
+ namespace std::ranges {
348
+ template<weakly_incrementable W, semiregular Bound>
349
+ requires weakly-equality-comparable-with<W, Bound>
350
+ struct iota_view<W, Bound>::iterator {
351
+ private:
352
+ W value_ = W(); // exposition only
353
+ public:
354
+ using iterator_concept = see below;
355
+ using iterator_category = input_iterator_tag;
356
+ using value_type = W;
357
+ using difference_type = IOTA-DIFF-T(W);
358
+
359
+ iterator() = default;
360
+ constexpr explicit iterator(W value);
361
+
362
+ constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);
363
+
364
+ constexpr iterator& operator++();
365
+ constexpr void operator++(int);
366
+ constexpr iterator operator++(int) requires incrementable<W>;
367
+
368
+ constexpr iterator& operator--() requires decrementable<W>;
369
+ constexpr iterator operator--(int) requires decrementable<W>;
370
+
371
+ constexpr iterator& operator+=(difference_type n)
372
+ requires advanceable<W>;
373
+ constexpr iterator& operator-=(difference_type n)
374
+ requires advanceable<W>;
375
+ constexpr W operator[](difference_type n) const
376
+ requires advanceable<W>;
377
+
378
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
379
+ requires equality_comparable<W>;
380
+
381
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
382
+ requires totally_ordered<W>;
383
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
384
+ requires totally_ordered<W>;
385
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
386
+ requires totally_ordered<W>;
387
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
388
+ requires totally_ordered<W>;
389
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
390
+ requires totally_ordered<W> && three_way_comparable<W>;
391
+
392
+ friend constexpr iterator operator+(iterator i, difference_type n)
393
+ requires advanceable<W>;
394
+ friend constexpr iterator operator+(difference_type n, iterator i)
395
+ requires advanceable<W>;
396
+
397
+ friend constexpr iterator operator-(iterator i, difference_type n)
398
+ requires advanceable<W>;
399
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
400
+ requires advanceable<W>;
401
+ };
402
+ }
403
+ ```
404
+
405
+ `iterator::iterator_concept` is defined as follows:
406
+
407
+ - If `W` models `advanceable`, then `iterator_concept` is
408
+ `random_access_iterator_tag`.
409
+ - Otherwise, if `W` models `decrementable`, then `iterator_concept` is
410
+ `bidirectional_iterator_tag`.
411
+ - Otherwise, if `W` models `incrementable`, then `iterator_concept` is
412
+ `forward_iterator_tag`.
413
+ - Otherwise, `iterator_concept` is `input_iterator_tag`.
414
+
415
+ [*Note 1*: Overloads for `iter_move` and `iter_swap` are omitted
416
+ intentionally. — *end note*]
417
+
418
+ ``` cpp
419
+ constexpr explicit iterator(W value);
420
+ ```
421
+
422
+ *Effects:* Initializes *value\_* with `value`.
423
+
424
+ ``` cpp
425
+ constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);
426
+ ```
427
+
428
+ *Effects:* Equivalent to: `return `*`value_`*`;`
429
+
430
+ [*Note 1*: The `noexcept` clause is needed by the default `iter_move`
431
+ implementation. — *end note*]
432
+
433
+ ``` cpp
434
+ constexpr iterator& operator++();
435
+ ```
436
+
437
+ *Effects:* Equivalent to:
438
+
439
+ ``` cpp
440
+ ++value_;
441
+ return *this;
442
+ ```
443
+
444
+ ``` cpp
445
+ constexpr void operator++(int);
446
+ ```
447
+
448
+ *Effects:* Equivalent to `++*this`.
449
+
450
+ ``` cpp
451
+ constexpr iterator operator++(int) requires incrementable<W>;
452
+ ```
453
+
454
+ *Effects:* Equivalent to:
455
+
456
+ ``` cpp
457
+ auto tmp = *this;
458
+ ++*this;
459
+ return tmp;
460
+ ```
461
+
462
+ ``` cpp
463
+ constexpr iterator& operator--() requires decrementable<W>;
464
+ ```
465
+
466
+ *Effects:* Equivalent to:
467
+
468
+ ``` cpp
469
+ --value_;
470
+ return *this;
471
+ ```
472
+
473
+ ``` cpp
474
+ constexpr iterator operator--(int) requires decrementable<W>;
475
+ ```
476
+
477
+ *Effects:* Equivalent to:
478
+
479
+ ``` cpp
480
+ auto tmp = *this;
481
+ --*this;
482
+ return tmp;
483
+ ```
484
+
485
+ ``` cpp
486
+ constexpr iterator& operator+=(difference_type n)
487
+ requires advanceable<W>;
488
+ ```
489
+
490
+ *Effects:* Equivalent to:
491
+
492
+ ``` cpp
493
+ if constexpr (is-integer-like<W> && !is-signed-integer-like<W>) {
494
+ if (n >= difference_type(0))
495
+ value_ += static_cast<W>(n);
496
+ else
497
+ value_ -= static_cast<W>(-n);
498
+ } else {
499
+ value_ += n;
500
+ }
501
+ return *this;
502
+ ```
503
+
504
+ ``` cpp
505
+ constexpr iterator& operator-=(difference_type n)
506
+ requires advanceable<W>;
507
+ ```
508
+
509
+ *Effects:* Equivalent to:
510
+
511
+ ``` cpp
512
+ if constexpr (is-integer-like<W> && !is-signed-integer-like<W>) {
513
+ if (n >= difference_type(0))
514
+ value_ -= static_cast<W>(n);
515
+ else
516
+ value_ += static_cast<W>(-n);
517
+ } else {
518
+ value_ -= n;
519
+ }
520
+ return *this;
521
+ ```
522
+
523
+ ``` cpp
524
+ constexpr W operator[](difference_type n) const
525
+ requires advanceable<W>;
526
+ ```
527
+
528
+ *Effects:* Equivalent to: `return W(`*`value_`*` + n);`
529
+
530
+ ``` cpp
531
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
532
+ requires equality_comparable<W>;
533
+ ```
534
+
535
+ *Effects:* Equivalent to: `return x.`*`value_`*` == y.`*`value_`*`;`
536
+
537
+ ``` cpp
538
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
539
+ requires totally_ordered<W>;
540
+ ```
541
+
542
+ *Effects:* Equivalent to: `return x.`*`value_`*` < y.`*`value_`*`;`
543
+
544
+ ``` cpp
545
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
546
+ requires totally_ordered<W>;
547
+ ```
548
+
549
+ *Effects:* Equivalent to: `return y < x;`
550
+
551
+ ``` cpp
552
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
553
+ requires totally_ordered<W>;
554
+ ```
555
+
556
+ *Effects:* Equivalent to: `return !(y < x);`
557
+
558
+ ``` cpp
559
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
560
+ requires totally_ordered<W>;
561
+ ```
562
+
563
+ *Effects:* Equivalent to: `return !(x < y);`
564
+
565
+ ``` cpp
566
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
567
+ requires totally_ordered<W> && three_way_comparable<W>;
568
+ ```
569
+
570
+ *Effects:* Equivalent to: `return x.`*`value_`*` <=> y.`*`value_`*`;`
571
+
572
+ ``` cpp
573
+ friend constexpr iterator operator+(iterator i, difference_type n)
574
+ requires advanceable<W>;
575
+ ```
576
+
577
+ *Effects:* Equivalent to: `return i += n;`
578
+
579
+ ``` cpp
580
+ friend constexpr iterator operator+(difference_type n, iterator i)
581
+ requires advanceable<W>;
582
+ ```
583
+
584
+ *Effects:* Equivalent to: `return i + n;`
585
+
586
+ ``` cpp
587
+ friend constexpr iterator operator-(iterator i, difference_type n)
588
+ requires advanceable<W>;
589
+ ```
590
+
591
+ *Effects:* Equivalent to: `return i -= n;`
592
+
593
+ ``` cpp
594
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
595
+ requires advanceable<W>;
596
+ ```
597
+
598
+ *Effects:* Equivalent to:
599
+
600
+ ``` cpp
601
+ using D = difference_type;
602
+ if constexpr (is-integer-like<W>) {
603
+ if constexpr (is-signed-integer-like<W>)
604
+ return D(D(x.value_) - D(y.value_));
605
+ else
606
+ return (y.value_ > x.value_)
607
+ ? D(-D(y.value_ - x.value_))
608
+ : D(x.value_ - y.value_);
609
+ } else {
610
+ return x.value_ - y.value_;
611
+ }
612
+ ```
613
+
614
+ #### Class `iota_view::sentinel` <a id="range.iota.sentinel">[[range.iota.sentinel]]</a>
615
+
616
+ ``` cpp
617
+ namespace std::ranges {
618
+ template<weakly_incrementable W, semiregular Bound>
619
+ requires weakly-equality-comparable-with<W, Bound>
620
+ struct iota_view<W, Bound>::sentinel {
621
+ private:
622
+ Bound bound_ = Bound(); // exposition only
623
+ public:
624
+ sentinel() = default;
625
+ constexpr explicit sentinel(Bound bound);
626
+
627
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
628
+
629
+ friend constexpr iter_difference_t<W> operator-(const iterator& x, const sentinel& y)
630
+ requires sized_sentinel_for<Bound, W>;
631
+ friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterator& y)
632
+ requires sized_sentinel_for<Bound, W>;
633
+ };
634
+ }
635
+ ```
636
+
637
+ ``` cpp
638
+ constexpr explicit sentinel(Bound bound);
639
+ ```
640
+
641
+ *Effects:* Initializes *bound\_* with `bound`.
642
+
643
+ ``` cpp
644
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
645
+ ```
646
+
647
+ *Effects:* Equivalent to: `return x.`*`value_`*` == y.`*`bound_`*`;`
648
+
649
+ ``` cpp
650
+ friend constexpr iter_difference_t<W> operator-(const iterator& x, const sentinel& y)
651
+ requires sized_sentinel_for<Bound, W>;
652
+ ```
653
+
654
+ *Effects:* Equivalent to: `return x.`*`value_`*` - y.`*`bound_`*`;`
655
+
656
+ ``` cpp
657
+ friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterator& y)
658
+ requires sized_sentinel_for<Bound, W>;
659
+ ```
660
+
661
+ *Effects:* Equivalent to: `return -(y - x);`
662
+
663
+ ### Istream view <a id="range.istream">[[range.istream]]</a>
664
+
665
+ #### Overview <a id="range.istream.overview">[[range.istream.overview]]</a>
666
+
667
+ `basic_istream_view` models `input_range` and reads (using `operator>>`)
668
+ successive elements from its corresponding input stream.
669
+
670
+ [*Example 1*:
671
+
672
+ ``` cpp
673
+ auto ints = istringstream{"0 1 2 3 4"};
674
+ ranges::copy(istream_view<int>(ints), ostream_iterator<int>{cout, "-"});
675
+ // prints 0-1-2-3-4-
676
+ ```
677
+
678
+ — *end example*]
679
+
680
+ #### Class template `basic_istream_view` <a id="range.istream.view">[[range.istream.view]]</a>
681
+
682
+ ``` cpp
683
+ namespace std::ranges {
684
+ template<class Val, class CharT, class Traits>
685
+ concept stream-extractable = // exposition only
686
+ requires(basic_istream<CharT, Traits>& is, Val& t) {
687
+ is >> t;
688
+ };
689
+
690
+ template<movable Val, class CharT, class Traits>
691
+ requires default_initializable<Val> &&
692
+ stream-extractable<Val, CharT, Traits>
693
+ class basic_istream_view : public view_interface<basic_istream_view<Val, CharT, Traits>> {
694
+ public:
695
+ basic_istream_view() = default;
696
+ constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);
697
+
698
+ constexpr auto begin()
699
+ {
700
+ if (stream_) {
701
+ *stream_ >> object_;
702
+ }
703
+ return iterator{*this};
704
+ }
705
+
706
+ constexpr default_sentinel_t end() const noexcept;
707
+
708
+ private:
709
+ struct iterator; // exposition only
710
+ basic_istream<CharT, Traits>* stream_ = nullptr; // exposition only
711
+ Val object_ = Val(); // exposition only
712
+ };
713
+ }
714
+ ```
715
+
716
+ ``` cpp
717
+ constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);
718
+ ```
719
+
720
+ *Effects:* Initializes *stream\_* with `addressof(stream)`.
721
+
722
+ ``` cpp
723
+ constexpr default_sentinel_t end() const noexcept;
724
+ ```
725
+
726
+ *Effects:* Equivalent to: `return default_sentinel;`
727
+
728
+ ``` cpp
729
+ template<class Val, class CharT, class Traits>
730
+ basic_istream_view<Val, CharT, Traits> istream_view(basic_istream<CharT, Traits>& s);
731
+ ```
732
+
733
+ *Effects:* Equivalent to:
734
+ `return basic_istream_view<Val, CharT, Traits>{s};`
735
+
736
+ #### Class template `basic_istream_view::iterator` <a id="range.istream.iterator">[[range.istream.iterator]]</a>
737
+
738
+ ``` cpp
739
+ namespace std::ranges {
740
+ template<movable Val, class CharT, class Traits>
741
+ requires default_initializable<Val> &&
742
+ stream-extractable<Val, CharT, Traits>
743
+ class basic_istream_view<Val, CharT, Traits>::iterator { // exposition only
744
+ public:
745
+ using iterator_concept = input_iterator_tag;
746
+ using difference_type = ptrdiff_t;
747
+ using value_type = Val;
748
+
749
+ iterator() = default;
750
+ constexpr explicit iterator(basic_istream_view& parent) noexcept;
751
+
752
+ iterator(const iterator&) = delete;
753
+ iterator(iterator&&) = default;
754
+
755
+ iterator& operator=(const iterator&) = delete;
756
+ iterator& operator=(iterator&&) = default;
757
+
758
+ iterator& operator++();
759
+ void operator++(int);
760
+
761
+ Val& operator*() const;
762
+
763
+ friend bool operator==(const iterator& x, default_sentinel_t);
764
+
765
+ private:
766
+ basic_istream_view* parent_ = nullptr; // exposition only
767
+ };
768
+ }
769
+ ```
770
+
771
+ ``` cpp
772
+ constexpr explicit iterator(basic_istream_view& parent) noexcept;
773
+ ```
774
+
775
+ *Effects:* Initializes *parent\_* with `addressof(parent)`.
776
+
777
+ ``` cpp
778
+ iterator& operator++();
779
+ ```
780
+
781
+ *Preconditions:* *`parent_`*`->`*`stream_`*` != nullptr` is `true`.
782
+
783
+ *Effects:* Equivalent to:
784
+
785
+ ``` cpp
786
+ *parent_->stream_>> parent_->object_;
787
+ return *this;
788
+ ```
789
+
790
+ ``` cpp
791
+ void operator++(int);
792
+ ```
793
+
794
+ *Preconditions:* *`parent_`*`->`*`stream_`*` != nullptr` is `true`.
795
+
796
+ *Effects:* Equivalent to `++*this`.
797
+
798
+ ``` cpp
799
+ Val& operator*() const;
800
+ ```
801
+
802
+ *Preconditions:* *`parent_`*`->`*`stream_`*` != nullptr` is `true`.
803
+
804
+ *Effects:* Equivalent to: `return `*`parent_`*`->`*`object_`*`;`
805
+
806
+ ``` cpp
807
+ friend bool operator==(const iterator& x, default_sentinel_t);
808
+ ```
809
+
810
+ *Effects:* Equivalent to:
811
+ `return x.`*`parent_`*` == nullptr || !*x.`*`parent_`*`->`*`stream_`*`;`
812
+