From Jason Turner

[range.slide]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwylxwmuk/{from.md → to.md} +495 -0
tmp/tmpwylxwmuk/{from.md → to.md} RENAMED
@@ -0,0 +1,495 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Slide view <a id="range.slide">[[range.slide]]</a>
2
+
3
+ #### Overview <a id="range.slide.overview">[[range.slide.overview]]</a>
4
+
5
+ `slide_view` takes a view and a number N and produces a view whose Mᵗʰ
6
+ element is a view over the Mᵗʰ through (M + N - 1)ᵗʰ elements of the
7
+ original view. If the original view has fewer than N elements, the
8
+ resulting view is empty.
9
+
10
+ The name `views::slide` denotes a range adaptor object
11
+ [[range.adaptor.object]]. Given subexpressions `E` and `N`, the
12
+ expression `views::slide(E, N)` is expression-equivalent to
13
+ `slide_view(E, N)`.
14
+
15
+ [*Example 1*:
16
+
17
+ ``` cpp
18
+ vector v = {1, 2, 3, 4};
19
+
20
+ for (auto i : v | views::slide(2)) {
21
+ cout << '[' << i[0] << ", " << i[1] << "] "; // prints [1, 2] [2, 3] [3, 4]
22
+ }
23
+ ```
24
+
25
+ — *end example*]
26
+
27
+ #### Class template `slide_view` <a id="range.slide.view">[[range.slide.view]]</a>
28
+
29
+ ``` cpp
30
+ namespace std::ranges {
31
+ template<class V>
32
+ concept slide-caches-nothing = random_access_range<V> && sized_range<V>; // exposition only
33
+
34
+ template<class V>
35
+ concept slide-caches-last = // exposition only
36
+ !slide-caches-nothing<V> && bidirectional_range<V> && common_range<V>;
37
+
38
+ template<class V>
39
+ concept slide-caches-first = // exposition only
40
+ !slide-caches-nothing<V> && !slide-caches-last<V>;
41
+
42
+ template<forward_range V>
43
+ requires view<V>
44
+ class slide_view : public view_interface<slide_view<V>> {
45
+ V base_; // exposition only
46
+ range_difference_t<V> n_; // exposition only
47
+
48
+ // [range.slide.iterator], class template slide_view::iterator
49
+ template<bool> class iterator; // exposition only
50
+
51
+ // [range.slide.sentinel], class slide_view::sentinel
52
+ class sentinel; // exposition only
53
+
54
+ public:
55
+ constexpr explicit slide_view(V base, range_difference_t<V> n);
56
+
57
+ constexpr V base() const & requires copy_constructible<V> { return base_; }
58
+ constexpr V base() && { return std::move(base_); }
59
+
60
+ constexpr auto begin()
61
+ requires (!(simple-view<V> && slide-caches-nothing<const V>));
62
+ constexpr auto begin() const requires slide-caches-nothing<const V>;
63
+
64
+ constexpr auto end()
65
+ requires (!(simple-view<V> && slide-caches-nothing<const V>));
66
+ constexpr auto end() const requires slide-caches-nothing<const V>;
67
+
68
+ constexpr auto size() requires sized_range<V>;
69
+ constexpr auto size() const requires sized_range<const V>;
70
+ };
71
+
72
+ template<class R>
73
+ slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
74
+ }
75
+ ```
76
+
77
+ ``` cpp
78
+ constexpr explicit slide_view(V base, range_difference_t<V> n);
79
+ ```
80
+
81
+ *Preconditions:* `n > 0` is `true`.
82
+
83
+ *Effects:* Initializes *base\_* with `std::move(base)` and *n\_* with
84
+ `n`.
85
+
86
+ ``` cpp
87
+ constexpr auto begin()
88
+ requires (!(simple-view<V> && slide-caches-nothing<const V>));
89
+ ```
90
+
91
+ *Returns:*
92
+
93
+ - If `V` models `slide-caches-first`,
94
+ ``` cpp
95
+ iterator<false>(ranges::begin(base_),
96
+ ranges::next(ranges::begin(base_), n_ - 1, ranges::end(base_)), n_)
97
+ ```
98
+ - Otherwise,
99
+ *`iterator`*`<false>(ranges::begin(`*`base_`*`), `*`n_`*`)`.
100
+
101
+ *Remarks:* In order to provide the amortized constant-time complexity
102
+ required by the `range` concept, this function caches the result within
103
+ the `slide_view` for use on subsequent calls when `V` models
104
+ `slide-caches-first`.
105
+
106
+ ``` cpp
107
+ constexpr auto begin() const requires slide-caches-nothing<const V>;
108
+ ```
109
+
110
+ *Returns:* *`iterator`*`<true>(ranges::begin(`*`base_`*`), `*`n_`*`)`.
111
+
112
+ ``` cpp
113
+ constexpr auto end()
114
+ requires (!(simple-view<V> && slide-caches-nothing<const V>));
115
+ ```
116
+
117
+ *Returns:*
118
+
119
+ - If `V` models `slide-caches-nothing`,
120
+ ``` cpp
121
+ iterator<false>(ranges::begin(base_) + range_difference_t<V>(size()), n_)
122
+ ```
123
+ - Otherwise, if `V` models `slide-caches-last`,
124
+ ``` cpp
125
+ iterator<false>(ranges::prev(ranges::end(base_), n_ - 1, ranges::begin(base_)), n_)
126
+ ```
127
+ - Otherwise, if `V` models `common_range`,
128
+ ``` cpp
129
+ iterator<false>(ranges::end(base_), ranges::end(base_), n_)
130
+ ```
131
+ - Otherwise, *`sentinel`*`(ranges::end(`*`base_`*`))`.
132
+
133
+ *Remarks:* In order to provide the amortized constant-time complexity
134
+ required by the `range` concept, this function caches the result within
135
+ the `slide_view` for use on subsequent calls when `V` models
136
+ `slide-caches-last`.
137
+
138
+ ``` cpp
139
+ constexpr auto end() const requires slide-caches-nothing<const V>;
140
+ ```
141
+
142
+ *Returns:* `begin() + range_difference_t<const V>(size())`.
143
+
144
+ ``` cpp
145
+ constexpr auto size() requires sized_range<V>;
146
+ constexpr auto size() const requires sized_range<const V>;
147
+ ```
148
+
149
+ *Effects:* Equivalent to:
150
+
151
+ ``` cpp
152
+ auto sz = ranges::distance(base_) - n_ + 1;
153
+ if (sz < 0) sz = 0;
154
+ return to-unsigned-like(sz);
155
+ ```
156
+
157
+ #### Class template `slide_view::iterator` <a id="range.slide.iterator">[[range.slide.iterator]]</a>
158
+
159
+ ``` cpp
160
+ namespace std::ranges {
161
+ template<forward_range V>
162
+ requires view<V>
163
+ template<bool Const>
164
+ class slide_view<V>::iterator {
165
+ using Base = maybe-const<Const, V>; // exposition only
166
+ iterator_t<Base> current_ = iterator_t<Base>(); // exposition only
167
+ iterator_t<Base> last_ele_ = iterator_t<Base>(); // exposition only,
168
+ // present only if Base models slide-caches-first
169
+ range_difference_t<Base> n_ = 0; // exposition only
170
+
171
+ constexpr iterator(iterator_t<Base> current, range_difference_t<Base> n) // exposition only
172
+ requires (!slide-caches-first<Base>);
173
+
174
+ constexpr iterator(iterator_t<Base> current, iterator_t<Base> last_ele, // exposition only
175
+ range_difference_t<Base> n)
176
+ requires slide-caches-first<Base>;
177
+
178
+ public:
179
+ using iterator_category = input_iterator_tag;
180
+ using iterator_concept = see below;
181
+ using value_type = decltype(views::counted(current_, n_));
182
+ using difference_type = range_difference_t<Base>;
183
+
184
+ iterator() = default;
185
+ constexpr iterator(iterator<!Const> i)
186
+ requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
187
+
188
+ constexpr auto operator*() const;
189
+ constexpr iterator& operator++();
190
+ constexpr iterator operator++(int);
191
+
192
+ constexpr iterator& operator--() requires bidirectional_range<Base>;
193
+ constexpr iterator operator--(int) requires bidirectional_range<Base>;
194
+
195
+ constexpr iterator& operator+=(difference_type x)
196
+ requires random_access_range<Base>;
197
+ constexpr iterator& operator-=(difference_type x)
198
+ requires random_access_range<Base>;
199
+
200
+ constexpr auto operator[](difference_type n) const
201
+ requires random_access_range<Base>;
202
+
203
+ friend constexpr bool operator==(const iterator& x, const iterator& y);
204
+
205
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
206
+ requires random_access_range<Base>;
207
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
208
+ requires random_access_range<Base>;
209
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
210
+ requires random_access_range<Base>;
211
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
212
+ requires random_access_range<Base>;
213
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
214
+ requires random_access_range<Base> &&
215
+ three_way_comparable<iterator_t<Base>>;
216
+
217
+ friend constexpr iterator operator+(const iterator& i, difference_type n)
218
+ requires random_access_range<Base>;
219
+ friend constexpr iterator operator+(difference_type n, const iterator& i)
220
+ requires random_access_range<Base>;
221
+ friend constexpr iterator operator-(const iterator& i, difference_type n)
222
+ requires random_access_range<Base>;
223
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
224
+ requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
225
+ };
226
+ }
227
+ ```
228
+
229
+ `iterator::iterator_concept` is defined as follows:
230
+
231
+ - If *`Base`* models `random_access_range`, then `iterator_concept`
232
+ denotes `random_access_iterator_tag`.
233
+ - Otherwise, if *`Base`* models `bidirectional_range`, then
234
+ `iterator_concept` denotes `bidirectional_iterator_tag`.
235
+ - Otherwise, `iterator_concept` denotes `forward_iterator_tag`.
236
+
237
+ If the invocation of any non-const member function of *`iterator`* exits
238
+ via an exception, the *`iterator`* acquires a singular value.
239
+
240
+ ``` cpp
241
+ constexpr iterator(iterator_t<Base> current, range_difference_t<Base> n)
242
+ requires (!slide-caches-first<Base>);
243
+ ```
244
+
245
+ *Effects:* Initializes *current\_* with `current` and *n\_* with `n`.
246
+
247
+ ``` cpp
248
+ constexpr iterator(iterator_t<Base> current, iterator_t<Base> last_ele,
249
+ range_difference_t<Base> n)
250
+ requires slide-caches-first<Base>;
251
+ ```
252
+
253
+ *Effects:* Initializes *current\_* with `current`, *last_ele\_* with
254
+ `last_ele`, and *n\_* with `n`.
255
+
256
+ ``` cpp
257
+ constexpr iterator(iterator<!Const> i)
258
+ requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
259
+ ```
260
+
261
+ *Effects:* Initializes *current\_* with `std::move(i.`*`current_`*`)`
262
+ and *n\_* with `i.`*`n_`*.
263
+
264
+ [*Note 1*: *`iterator`*`<true>` can only be formed when *Base* models
265
+ `slide-caches-nothing`, in which case *last_ele\_* is not
266
+ present. — *end note*]
267
+
268
+ ``` cpp
269
+ constexpr auto operator*() const;
270
+ ```
271
+
272
+ *Returns:* `views::counted(`*`current_`*`, `*`n_`*`)`.
273
+
274
+ ``` cpp
275
+ constexpr iterator& operator++();
276
+ ```
277
+
278
+ *Preconditions:* *current\_* and *last_ele\_* (if present) are
279
+ incrementable.
280
+
281
+ *Ensures:* *current\_* and *last_ele\_* (if present) are each equal to
282
+ `ranges::next(i)`, where `i` is the value of that data member before the
283
+ call.
284
+
285
+ *Returns:* `*this`.
286
+
287
+ ``` cpp
288
+ constexpr iterator operator++(int);
289
+ ```
290
+
291
+ *Effects:* Equivalent to:
292
+
293
+ ``` cpp
294
+ auto tmp = *this;
295
+ ++*this;
296
+ return tmp;
297
+ ```
298
+
299
+ ``` cpp
300
+ constexpr iterator& operator--() requires bidirectional_range<Base>;
301
+ ```
302
+
303
+ *Preconditions:* *current\_* and *last_ele\_* (if present) are
304
+ decrementable.
305
+
306
+ *Ensures:* *current\_* and *last_ele\_* (if present) are each equal to
307
+ `ranges::prev(i)`, where `i` is the value of that data member before the
308
+ call.
309
+
310
+ *Returns:* `*this`.
311
+
312
+ ``` cpp
313
+ constexpr iterator operator--(int) requires bidirectional_range<Base>;
314
+ ```
315
+
316
+ *Effects:* Equivalent to:
317
+
318
+ ``` cpp
319
+ auto tmp = *this;
320
+ --*this;
321
+ return tmp;
322
+ ```
323
+
324
+ ``` cpp
325
+ constexpr iterator& operator+=(difference_type x)
326
+ requires random_access_range<Base>;
327
+ ```
328
+
329
+ *Preconditions:* *`current_`*` + x` and *`last_ele_`*` + x` (if
330
+ *last_ele\_* is present) have well-defined behavior.
331
+
332
+ *Ensures:* *current\_* and *last_ele\_* (if present) are each equal to
333
+ `i + x`, where `i` is the value of that data member before the call.
334
+
335
+ *Returns:* `*this`.
336
+
337
+ ``` cpp
338
+ constexpr iterator& operator-=(difference_type x)
339
+ requires random_access_range<Base>;
340
+ ```
341
+
342
+ *Preconditions:* *`current_`*` - x` and *`last_ele_`*` - x` (if
343
+ *last_ele\_* is present) have well-defined behavior.
344
+
345
+ *Ensures:* *current\_* and *last_ele\_* (if present) are each equal to
346
+ `i - x`, where `i` is the value of that data member before the call.
347
+
348
+ *Returns:* `*this`.
349
+
350
+ ``` cpp
351
+ constexpr auto operator[](difference_type n) const
352
+ requires random_access_range<Base>;
353
+ ```
354
+
355
+ *Effects:* Equivalent to:
356
+ `return views::counted(`*`current_`*` + n, `*`n_`*`);`
357
+
358
+ ``` cpp
359
+ friend constexpr bool operator==(const iterator& x, const iterator& y);
360
+ ```
361
+
362
+ *Returns:* If *last_ele\_* is present,
363
+ `x.`*`last_ele_`*` == y.`*`last_ele_`*; otherwise,
364
+ `x.`*`current_`*` == y.`*`current_`*.
365
+
366
+ ``` cpp
367
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
368
+ requires random_access_range<Base>;
369
+ ```
370
+
371
+ *Returns:* `x.`*`current_`*` < y.`*`current_`*.
372
+
373
+ ``` cpp
374
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
375
+ requires random_access_range<Base>;
376
+ ```
377
+
378
+ *Effects:* Equivalent to: `return y < x;`
379
+
380
+ ``` cpp
381
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
382
+ requires random_access_range<Base>;
383
+ ```
384
+
385
+ *Effects:* Equivalent to: `return !(y < x);`
386
+
387
+ ``` cpp
388
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
389
+ requires random_access_range<Base>;
390
+ ```
391
+
392
+ *Effects:* Equivalent to: `return !(x < y);`
393
+
394
+ ``` cpp
395
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
396
+ requires random_access_range<Base> &&
397
+ three_way_comparable<iterator_t<Base>>;
398
+ ```
399
+
400
+ *Returns:* `x.`*`current_`*` <=> y.`*`current_`*.
401
+
402
+ ``` cpp
403
+ friend constexpr iterator operator+(const iterator& i, difference_type n)
404
+ requires random_access_range<Base>;
405
+ friend constexpr iterator operator+(difference_type n, const iterator& i)
406
+ requires random_access_range<Base>;
407
+ ```
408
+
409
+ *Effects:* Equivalent to:
410
+
411
+ ``` cpp
412
+ auto r = i;
413
+ r += n;
414
+ return r;
415
+ ```
416
+
417
+ ``` cpp
418
+ friend constexpr iterator operator-(const iterator& i, difference_type n)
419
+ requires random_access_range<Base>;
420
+ ```
421
+
422
+ *Effects:* Equivalent to:
423
+
424
+ ``` cpp
425
+ auto r = i;
426
+ r -= n;
427
+ return r;
428
+ ```
429
+
430
+ ``` cpp
431
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
432
+ requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
433
+ ```
434
+
435
+ *Returns:* If *last_ele\_* is present,
436
+ `x.`*`last_ele_`*` - y.`*`last_ele_`*; otherwise,
437
+ `x.`*`current_`*` - y.`*`current_`*.
438
+
439
+ #### Class `slide_view::sentinel` <a id="range.slide.sentinel">[[range.slide.sentinel]]</a>
440
+
441
+ ``` cpp
442
+ namespace std::ranges {
443
+ template<forward_range V>
444
+ requires view<V>
445
+ class slide_view<V>::sentinel {
446
+ sentinel_t<V> end_ = sentinel_t<V>(); // exposition only
447
+ constexpr explicit sentinel(sentinel_t<V> end); // exposition only
448
+
449
+ public:
450
+ sentinel() = default;
451
+
452
+ friend constexpr bool operator==(const iterator<false>& x, const sentinel& y);
453
+
454
+ friend constexpr range_difference_t<V>
455
+ operator-(const iterator<false>& x, const sentinel& y)
456
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
457
+
458
+ friend constexpr range_difference_t<V>
459
+ operator-(const sentinel& y, const iterator<false>& x)
460
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
461
+ };
462
+ }
463
+ ```
464
+
465
+ [*Note 1*: *`sentinel`* is used only when `slide-caches-first<V>` is
466
+ `true`. — *end note*]
467
+
468
+ ``` cpp
469
+ constexpr explicit sentinel(sentinel_t<V> end);
470
+ ```
471
+
472
+ *Effects:* Initializes *end\_* with `end`.
473
+
474
+ ``` cpp
475
+ friend constexpr bool operator==(const iterator<false>& x, const sentinel& y);
476
+ ```
477
+
478
+ *Returns:* `x.`*`last_ele_`*` == y.`*`end_`*.
479
+
480
+ ``` cpp
481
+ friend constexpr range_difference_t<V>
482
+ operator-(const iterator<false>& x, const sentinel& y)
483
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
484
+ ```
485
+
486
+ *Returns:* `x.`*`last_ele_`*` - y.`*`end_`*.
487
+
488
+ ``` cpp
489
+ friend constexpr range_difference_t<V>
490
+ operator-(const sentinel& y, const iterator<false>& x)
491
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
492
+ ```
493
+
494
+ *Returns:* `y.`*`end_`*` - x.`*`last_ele_`*.
495
+