From Jason Turner

[range.transform]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpq4l37mnp/{from.md → to.md} +69 -78
tmp/tmpq4l37mnp/{from.md → to.md} RENAMED
@@ -1,49 +1,50 @@
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();
@@ -69,11 +70,11 @@ namespace std::ranges {
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
 
@@ -145,41 +146,41 @@ return iterator<true>{*this, ranges::end(base_)};
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
 
@@ -188,13 +189,15 @@ namespace std::ranges {
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)
@@ -214,43 +217,32 @@ namespace std::ranges {
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`.
@@ -269,21 +261,20 @@ constexpr iterator(iterator<!Const> i)
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
 
@@ -296,11 +287,11 @@ return *this;
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
 
@@ -408,67 +399,63 @@ friend constexpr iterator operator+(iterator i, difference_type n)
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
@@ -489,26 +476,30 @@ 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
 
 
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
+ auto squares = views::transform(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, move_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
+
37
  // [range.transform.sentinel], class template transform_view::sentinel
38
  template<bool> struct sentinel; // exposition only
39
 
40
  V base_ = V(); // exposition only
41
+ movable-box<F> fun_; // exposition only
42
 
43
  public:
44
+ transform_view() requires default_initializable<V> && default_initializable<F> = default;
45
+ constexpr explicit transform_view(V base, F fun);
46
 
47
  constexpr V base() const & requires copy_constructible<V> { return base_; }
48
  constexpr V base() && { return std::move(base_); }
49
 
50
  constexpr iterator<false> begin();
 
70
  transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
71
  }
72
  ```
73
 
74
  ``` cpp
75
+ constexpr explicit transform_view(V base, F fun);
76
  ```
77
 
78
  *Effects:* Initializes *base\_* with `std::move(base)` and *fun\_* with
79
  `std::move(fun)`.
80
 
 
146
 
147
  #### Class template `transform_view::iterator` <a id="range.transform.iterator">[[range.transform.iterator]]</a>
148
 
149
  ``` cpp
150
  namespace std::ranges {
151
+ template<input_range V, move_constructible F>
152
  requires view<V> && is_object_v<F> &&
153
  regular_invocable<F&, range_reference_t<V>> &&
154
  can-reference<invoke_result_t<F&, range_reference_t<V>>>
155
  template<bool Const>
156
  class transform_view<V, F>::iterator {
157
  private:
158
+ using Parent = maybe-const<Const, transform_view>; // exposition only
159
+ using Base = maybe-const<Const, V>; // exposition only
160
+ iterator_t<Base> current_ = iterator_t<Base>(); // exposition only
 
 
 
161
  Parent* parent_ = nullptr; // exposition only
162
+
163
  public:
164
+ using iterator_concept = see belownc;
165
+ using iterator_category = see belownc; // not always present
166
  using value_type =
167
+ remove_cvref_t<invoke_result_t<maybe-const<Const, F>&, range_reference_t<Base>>>;
168
  using difference_type = range_difference_t<Base>;
169
 
170
+ iterator() requires default_initializable<iterator_t<Base>> = default;
171
  constexpr iterator(Parent& parent, iterator_t<Base> current);
172
  constexpr iterator(iterator<!Const> i)
173
  requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
174
 
175
+ constexpr const iterator_t<Base>& base() const & noexcept;
 
176
  constexpr iterator_t<Base> base() &&;
177
+
178
  constexpr decltype(auto) operator*() const
179
+ noexcept(noexcept(invoke(*parent_->fun_, *current_))) {
180
+ return invoke(*parent_->fun_, *current_);
181
+ }
182
 
183
  constexpr iterator& operator++();
184
  constexpr void operator++(int);
185
  constexpr iterator operator++(int) requires forward_range<Base>;
186
 
 
189
 
190
  constexpr iterator& operator+=(difference_type n)
191
  requires random_access_range<Base>;
192
  constexpr iterator& operator-=(difference_type n)
193
  requires random_access_range<Base>;
194
+
195
  constexpr decltype(auto) operator[](difference_type n) const
196
+ requires random_access_range<Base> {
197
+ return invoke(*parent_->fun_, current_[n]);
198
+ }
199
 
200
  friend constexpr bool operator==(const iterator& x, const iterator& y)
201
  requires equality_comparable<iterator_t<Base>>;
202
 
203
  friend constexpr bool operator<(const iterator& x, const iterator& y)
 
217
  requires random_access_range<Base>;
218
 
219
  friend constexpr iterator operator-(iterator i, difference_type n)
220
  requires random_access_range<Base>;
221
  friend constexpr difference_type operator-(const iterator& x, const iterator& y)
222
+ requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  };
224
  }
225
  ```
226
 
227
  `iterator::iterator_concept` is defined as follows:
228
 
229
+ - If *`Base`* models `random_access_range`, then `iterator_concept`
230
+ denotes `random_access_iterator_tag`.
231
+ - Otherwise, if *`Base`* models `bidirectional_range`, then
232
  `iterator_concept` denotes `bidirectional_iterator_tag`.
233
+ - Otherwise, if *`Base`* models `forward_range`, then `iterator_concept`
234
  denotes `forward_iterator_tag`.
235
  - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
236
 
237
+ The member *typedef-name* `iterator_category` is defined if and only if
238
+ *`Base`* models `forward_range`. In that case,
239
  `iterator::iterator_category` is defined as follows: Let `C` denote the
240
  type `iterator_traits<iterator_t<Base>>::iterator_category`.
241
 
242
  - If
243
+ `is_reference_v<invoke_result_t<maybe-const<Const, F>&, range_reference_t<Base>>>`
244
  is `true`, then
245
  - if `C` models `derived_from<contiguous_iterator_tag>`,
246
  `iterator_category` denotes `random_access_iterator_tag`;
247
  - otherwise, `iterator_category` denotes `C`.
248
  - Otherwise, `iterator_category` denotes `input_iterator_tag`.
 
261
 
262
  *Effects:* Initializes *current\_* with `std::move(i.`*`current_`*`)`
263
  and *parent\_* with `i.`*`parent_`*.
264
 
265
  ``` cpp
266
+ constexpr const iterator_t<Base>& base() const & noexcept;
 
267
  ```
268
 
269
  *Effects:* Equivalent to: `return `*`current_`*`;`
270
 
271
  ``` cpp
272
  constexpr iterator_t<Base> base() &&;
273
  ```
274
 
275
+ *Effects:* Equivalent to: `return std::move(`*`current_`*`);`
276
 
277
  ``` cpp
278
  constexpr iterator& operator++();
279
  ```
280
 
 
287
 
288
  ``` cpp
289
  constexpr void operator++(int);
290
  ```
291
 
292
+ *Effects:* Equivalent to `++`*`current_`*.
293
 
294
  ``` cpp
295
  constexpr iterator operator++(int) requires forward_range<Base>;
296
  ```
297
 
 
399
  friend constexpr iterator operator+(difference_type n, iterator i)
400
  requires random_access_range<Base>;
401
  ```
402
 
403
  *Effects:* Equivalent to:
404
+ `return `*`iterator`*`{*i.`*`parent_`*`, i.`*`current_`*` + n};`
405
 
406
  ``` cpp
407
  friend constexpr iterator operator-(iterator i, difference_type n)
408
  requires random_access_range<Base>;
409
  ```
410
 
411
  *Effects:* Equivalent to:
412
+ `return `*`iterator`*`{*i.`*`parent_`*`, i.`*`current_`*` - n};`
413
 
414
  ``` cpp
415
  friend constexpr difference_type operator-(const iterator& x, const iterator& y)
416
+ requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
417
  ```
418
 
419
  *Effects:* Equivalent to: `return x.`*`current_`*` - y.`*`current_`*`;`
420
 
 
 
 
 
 
 
 
 
 
421
  #### Class template `transform_view::sentinel` <a id="range.transform.sentinel">[[range.transform.sentinel]]</a>
422
 
423
  ``` cpp
424
  namespace std::ranges {
425
+ template<input_range V, move_constructible F>
426
  requires view<V> && is_object_v<F> &&
427
  regular_invocable<F&, range_reference_t<V>> &&
428
  can-reference<invoke_result_t<F&, range_reference_t<V>>>
429
  template<bool Const>
430
  class transform_view<V, F>::sentinel {
431
  private:
432
+ using Parent = maybe-const<Const, transform_view>; // exposition only
433
+ using Base = maybe-const<Const, V>; // exposition only
 
434
  sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
435
+
436
  public:
437
  sentinel() = default;
438
  constexpr explicit sentinel(sentinel_t<Base> end);
439
  constexpr sentinel(sentinel<!Const> i)
440
  requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
441
 
442
  constexpr sentinel_t<Base> base() const;
443
 
444
+ template<bool OtherConst>
445
+ requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
446
+ friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
447
 
448
+ template<bool OtherConst>
449
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
450
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
451
+ operator-(const iterator<OtherConst>& x, const sentinel& y);
452
+
453
+ template<bool OtherConst>
454
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
455
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
456
+ operator-(const sentinel& y, const iterator<OtherConst>& x);
457
  };
458
  }
459
  ```
460
 
461
  ``` cpp
 
476
  ```
477
 
478
  *Effects:* Equivalent to: `return `*`end_`*`;`
479
 
480
  ``` cpp
481
+ template<bool OtherConst>
482
+ requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
483
+ friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
484
  ```
485
 
486
  *Effects:* Equivalent to: `return x.`*`current_`*` == y.`*`end_`*`;`
487
 
488
  ``` cpp
489
+ template<bool OtherConst>
490
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
491
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
492
+ operator-(const iterator<OtherConst>& x, const sentinel& y);
493
  ```
494
 
495
  *Effects:* Equivalent to: `return x.`*`current_`*` - y.`*`end_`*`;`
496
 
497
  ``` cpp
498
+ template<bool OtherConst>
499
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
500
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
501
+ operator-(const sentinel& y, const iterator<OtherConst>& x);
502
  ```
503
 
504
  *Effects:* Equivalent to: `return y.`*`end_`*` - x.`*`current_`*`;`
505