From Jason Turner

[range.transform]

Diff to HTML by rtfpessoa

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