From Jason Turner

[range.concat.iterator]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpoctr487i/{from.md → to.md} +577 -0
tmp/tmpoctr487i/{from.md → to.md} RENAMED
@@ -0,0 +1,577 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Class `concat_view::iterator` <a id="range.concat.iterator">[[range.concat.iterator]]</a>
2
+
3
+ ``` cpp
4
+ namespace std::ranges {
5
+ template<input_range... Views>
6
+ requires (view<Views> && ...) && (sizeof...(Views) > 0) &&
7
+ concatable<Views...>
8
+ template<bool Const>
9
+ class concat_view<Views...>::iterator {
10
+
11
+ public:
12
+ using iterator_category = see below; // not always present
13
+ using iterator_concept = see below;
14
+ using value_type = concat-value-t<maybe-const<Const, Views>...>;
15
+ using difference_type = common_type_t<range_difference_t<maybe-const<Const, Views>>...>;
16
+
17
+ private:
18
+ using base-iter = // exposition only
19
+ variant<iterator_t<maybe-const<Const, Views>>...>;
20
+
21
+ maybe-const<Const, concat_view>* parent_ = nullptr; // exposition only
22
+ base-iter it_; // exposition only
23
+
24
+ template<size_t N>
25
+ constexpr void satisfy(); // exposition only
26
+ template<size_t N>
27
+ constexpr void prev(); // exposition only
28
+
29
+ template<size_t N>
30
+ constexpr void advance-fwd(difference_type offset, // exposition only
31
+ difference_type steps);
32
+ template<size_t N>
33
+ constexpr void advance-bwd(difference_type offset, // exposition only
34
+ difference_type steps);
35
+
36
+ template<class... Args>
37
+ constexpr explicit iterator(maybe-const<Const, concat_view>* parent, // exposition only
38
+ Args&&... args)
39
+ requires constructible_from<base-iter, Args&&...>;
40
+
41
+ public:
42
+ iterator() = default;
43
+
44
+ constexpr iterator(iterator<!Const> i)
45
+ requires Const && (convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
46
+
47
+ constexpr decltype(auto) operator*() const;
48
+ constexpr iterator& operator++();
49
+ constexpr void operator++(int);
50
+ constexpr iterator operator++(int)
51
+ requires all-forward<Const, Views...>;
52
+ constexpr iterator& operator--()
53
+ requires concat-is-bidirectional<Const, Views...>;
54
+ constexpr iterator operator--(int)
55
+ requires concat-is-bidirectional<Const, Views...>;
56
+ constexpr iterator& operator+=(difference_type n)
57
+ requires concat-is-random-access<Const, Views...>;
58
+ constexpr iterator& operator-=(difference_type n)
59
+ requires concat-is-random-access<Const, Views...>;
60
+ constexpr decltype(auto) operator[](difference_type n) const
61
+ requires concat-is-random-access<Const, Views...>;
62
+
63
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
64
+ requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
65
+ friend constexpr bool operator==(const iterator& it, default_sentinel_t);
66
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
67
+ requires all-random-access<Const, Views...>;
68
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
69
+ requires all-random-access<Const, Views...>;
70
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
71
+ requires all-random-access<Const, Views...>;
72
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
73
+ requires all-random-access<Const, Views...>;
74
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
75
+ requires (all-random-access<Const, Views...> &&
76
+ (three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
77
+ friend constexpr iterator operator+(const iterator& it, difference_type n)
78
+ requires concat-is-random-access<Const, Views...>;
79
+ friend constexpr iterator operator+(difference_type n, const iterator& it)
80
+ requires concat-is-random-access<Const, Views...>;
81
+ friend constexpr iterator operator-(const iterator& it, difference_type n)
82
+ requires concat-is-random-access<Const, Views...>;
83
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
84
+ requires concat-is-random-access<Const, Views...>;
85
+ friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
86
+ requires see below;
87
+ friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
88
+ requires see below;
89
+ friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
90
+ friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
91
+ requires see below;
92
+ };
93
+ }
94
+ ```
95
+
96
+ `iterator::iterator_concept` is defined as follows:
97
+
98
+ - If `concat-is-random-access<Const, Views...>` is modeled, then
99
+ `iterator_concept` denotes `random_access_iterator_tag`.
100
+ - Otherwise, if `concat-is-bidirectional<Const, Views...>` is modeled,
101
+ then `iterator_concept` denotes `bidirectional_iterator_tag`.
102
+ - Otherwise, if `all-forward<Const, Views...>` is modeled, then
103
+ `iterator_concept` denotes `forward_iterator_tag`.
104
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
105
+
106
+ The member *typedef-name* `iterator_category` is defined if and only if
107
+ `all-forward<Const, Views...>` is modeled. In that case,
108
+ `iterator::iterator_category` is defined as follows:
109
+
110
+ - If `is_reference_v<concat-reference-t<maybe-const<Const, Views>...>>`
111
+ is `false`, then `iterator_category` denotes `input_iterator_tag`.
112
+ - Otherwise, let `Cs` denote the pack of types
113
+ `iterator_traits<iterator_t<maybe-const<Const, Views>>>::iterator_category...`.
114
+ - If
115
+ `(derived_from<Cs, random_access_iterator_tag> && ...) && concat-is-random-ac-{cess}<Const, Views...>`
116
+ is `true`, `iterator_category` denotes `random_access_iterator_tag`.
117
+ - Otherwise, if
118
+ `(derived_from<Cs, bidirectional_iterator_tag> && ...) && concat-is-{bidirectional}<Const, Views...>`
119
+ is `true`, `iterator_category` denotes `bidirectional_iterator_tag`.
120
+ - Otherwise, if `(derived_from<Cs, forward_iterator_tag> && ...)` is
121
+ `true`, `iterator_category` denotes `forward_iterator_tag`.
122
+ - Otherwise, `iterator_category` denotes `input_iterator_tag`.
123
+
124
+ ``` cpp
125
+ template<size_t N>
126
+ constexpr void satisfy();
127
+ ```
128
+
129
+ *Effects:* Equivalent to:
130
+
131
+ ``` cpp
132
+ if constexpr (N < (sizeof...(Views) - 1)) {
133
+ if (std::get<N>(it_) == ranges::end(std::get<N>(parent_->views_))) {
134
+ it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
135
+ satisfy<N + 1>();
136
+ }
137
+ }
138
+ ```
139
+
140
+ ``` cpp
141
+ template<size_t N>
142
+ constexpr void prev();
143
+ ```
144
+
145
+ *Effects:* Equivalent to:
146
+
147
+ ``` cpp
148
+ if constexpr (N == 0) {
149
+ --std::get<0>(it_);
150
+ } else {
151
+ if (std::get<N>(it_) == ranges::begin(std::get<N>(parent_->views_))) {
152
+ it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
153
+ prev<N - 1>();
154
+ } else {
155
+ --std::get<N>(it_);
156
+ }
157
+ }
158
+ ```
159
+
160
+ ``` cpp
161
+ template<size_t N>
162
+ constexpr void advance-fwd(difference_type offset, difference_type steps);
163
+ ```
164
+
165
+ *Effects:* Equivalent to:
166
+
167
+ ``` cpp
168
+ using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
169
+ if constexpr (N == sizeof...(Views) - 1) {
170
+ std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
171
+ } else {
172
+ auto n_size = ranges::distance(std::get<N>(parent_->views_));
173
+ if (offset + steps < n_size) {
174
+ std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
175
+ } else {
176
+ it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
177
+ advance-fwd<N + 1>(0, offset + steps - n_size);
178
+ }
179
+ }
180
+ ```
181
+
182
+ ``` cpp
183
+ template<size_t N>
184
+ constexpr void advance-bwd(difference_type offset, difference_type steps);
185
+ ```
186
+
187
+ *Effects:* Equivalent to:
188
+
189
+ ``` cpp
190
+ using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
191
+ if constexpr (N == 0) {
192
+ std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
193
+ } else {
194
+ if (offset >= steps) {
195
+ std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
196
+ } else {
197
+ auto prev_size = ranges::distance(std::get<N - 1>(parent_->views_));
198
+ it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
199
+ advance-bwd<N - 1>(prev_size, steps - offset);
200
+ }
201
+ }
202
+ ```
203
+
204
+ ``` cpp
205
+ template<class... Args>
206
+ constexpr explicit iterator(maybe-const<Const, concat_view>* parent,
207
+ Args&&... args)
208
+ requires constructible_from<base-iter, Args&&...>;
209
+ ```
210
+
211
+ *Effects:* Initializes *parent\_* with `parent`, and initializes *it\_*
212
+ with `std::forward<Args>(args)...`.
213
+
214
+ ``` cpp
215
+ constexpr iterator(iterator<!Const> it)
216
+ requires Const &&
217
+ (convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
218
+ ```
219
+
220
+ *Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
221
+
222
+ *Effects:* Initializes *parent\_* with `it.`*`parent_`*, and let i be
223
+ `it.`*`it_`*`.index()`, initializes *it\_* with
224
+ *`base-iter`*`(in_place_index<`i`>, std::get<`i`>(std::move(it.`*`it_`*`)))`.
225
+
226
+ ``` cpp
227
+ constexpr decltype(auto) operator*() const;
228
+ ```
229
+
230
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
231
+
232
+ *Effects:* Equivalent to:
233
+
234
+ ``` cpp
235
+ using reference = concat-reference-t<maybe-const<Const, Views>...>;
236
+ return std::visit([](auto&& it) -> reference { return *it; },
237
+ it_);
238
+ ```
239
+
240
+ ``` cpp
241
+ constexpr iterator& operator++();
242
+ ```
243
+
244
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
245
+
246
+ *Effects:* Let i be *`it_`*`.index()`. Equivalent to:
247
+
248
+ ``` cpp
249
+ ++std::get<i>(it_);
250
+ satisfy<i>();
251
+ return *this;
252
+ ```
253
+
254
+ ``` cpp
255
+ constexpr void operator++(int);
256
+ ```
257
+
258
+ *Effects:* Equivalent to:
259
+
260
+ ``` cpp
261
+ ++*this;
262
+ ```
263
+
264
+ ``` cpp
265
+ constexpr iterator operator++(int)
266
+ requires all-forward<Const, Views...>;
267
+ ```
268
+
269
+ *Effects:* Equivalent to:
270
+
271
+ ``` cpp
272
+ auto tmp = *this;
273
+ ++*this;
274
+ return tmp;
275
+ ```
276
+
277
+ ``` cpp
278
+ constexpr iterator& operator--()
279
+ requires concat-is-bidirectional<Const, Views...>;
280
+ ```
281
+
282
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
283
+
284
+ *Effects:* Let i be *`it_`*`.index()`. Equivalent to:
285
+
286
+ ``` cpp
287
+ prev<i>();
288
+ return *this;
289
+ ```
290
+
291
+ ``` cpp
292
+ constexpr iterator operator--(int)
293
+ requires concat-is-bidirectional<Const, Views...>;
294
+ ```
295
+
296
+ *Effects:* Equivalent to:
297
+
298
+ ``` cpp
299
+ auto tmp = *this;
300
+ --*this;
301
+ return tmp;
302
+ ```
303
+
304
+ ``` cpp
305
+ constexpr iterator& operator+=(difference_type n)
306
+ requires concat-is-random-access<Const, Views...>;
307
+ ```
308
+
309
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
310
+
311
+ *Effects:* Let i be *`it_`*`.index()`. Equivalent to:
312
+
313
+ ``` cpp
314
+ if (n > 0) {
315
+ advance-fwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), n);
316
+ } else if (n < 0) {
317
+ advance-bwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), -n);
318
+ }
319
+ return *this;
320
+ ```
321
+
322
+ ``` cpp
323
+ constexpr iterator& operator-=(difference_type n)
324
+ requires concat-is-random-access<Const, Views...>;
325
+ ```
326
+
327
+ *Effects:* Equivalent to:
328
+
329
+ ``` cpp
330
+ *this += -n;
331
+ return *this;
332
+ ```
333
+
334
+ ``` cpp
335
+ constexpr decltype(auto) operator[](difference_type n) const
336
+ requires concat-is-random-access<Const, Views...>;
337
+ ```
338
+
339
+ *Effects:* Equivalent to:
340
+
341
+ ``` cpp
342
+ return *((*this) + n);
343
+ ```
344
+
345
+ ``` cpp
346
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
347
+ requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
348
+ ```
349
+
350
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
351
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
352
+
353
+ *Effects:* Equivalent to:
354
+
355
+ ``` cpp
356
+ return x.it_ == y.it_;
357
+ ```
358
+
359
+ ``` cpp
360
+ friend constexpr bool operator==(const iterator& it, default_sentinel_t);
361
+ ```
362
+
363
+ *Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
364
+
365
+ *Effects:* Equivalent to:
366
+
367
+ ``` cpp
368
+ constexpr auto last_idx = sizeof...(Views) - 1;
369
+ return it.it_.index() == last_idx &&
370
+ std::get<last_idx>(it.it_) == ranges::end(std::get<last_idx>(it.parent_->views_));
371
+ ```
372
+
373
+ ``` cpp
374
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
375
+ requires all-random-access<Const, Views...>;
376
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
377
+ requires all-random-access<Const, Views...>;
378
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
379
+ requires all-random-access<Const, Views...>;
380
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
381
+ requires all-random-access<Const, Views...>;
382
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
383
+ requires (all-random-access<Const, Views...> &&
384
+ (three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
385
+ ```
386
+
387
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
388
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
389
+
390
+ Let op be the operator.
391
+
392
+ *Effects:* Equivalent to:
393
+
394
+ ``` cpp
395
+ return x.it_ op y.it_;
396
+ ```
397
+
398
+ ``` cpp
399
+ friend constexpr iterator operator+(const iterator& it, difference_type n)
400
+ requires concat-is-random-access<Const, Views...>;
401
+ ```
402
+
403
+ *Effects:* Equivalent to:
404
+
405
+ ``` cpp
406
+ auto temp = it;
407
+ temp += n;
408
+ return temp;
409
+ ```
410
+
411
+ ``` cpp
412
+ friend constexpr iterator operator+(difference_type n, const iterator& it)
413
+ requires concat-is-random-access<Const, Views...>;
414
+ ```
415
+
416
+ *Effects:* Equivalent to:
417
+
418
+ ``` cpp
419
+ return it + n;
420
+ ```
421
+
422
+ ``` cpp
423
+ friend constexpr iterator operator-(const iterator& it, difference_type n)
424
+ requires concat-is-random-access<Const, Views...>;
425
+ ```
426
+
427
+ *Effects:* Equivalent to:
428
+
429
+ ``` cpp
430
+ auto temp = it;
431
+ temp -= n;
432
+ return temp;
433
+ ```
434
+
435
+ ``` cpp
436
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
437
+ requires concat-is-random-access<Const, Views...>;
438
+ ```
439
+
440
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
441
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
442
+
443
+ *Effects:* Let i_`x` denote `x.`*`it_`*`.index()` and i_`y` denote
444
+ `y.`*`it_`*`.index()`.
445
+
446
+ - If i_`x`` > `i_`y`, let d_`y` be
447
+ `ranges::distance(std::get<`i_`y``>(y.`*`it_`*`), ranges::end(std::get<`i_`y``>(y.`*`parent_`*`->`*`views_`*`)))`,
448
+ d_`x` be
449
+ `ranges::distance(ranges::begin(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)), std::get<`i_`x``>(x.`*`it_`*`))`.
450
+ Let s denote the sum of the sizes of all the ranges
451
+ `std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
452
+ the range \[i_`y`` + 1`, i_`x`) if there is any, and `0` otherwise, of
453
+ type `difference_type`, equivalent to:
454
+ ``` cpp
455
+ return $d_y$ + s + $d_x$;
456
+ ```
457
+ - otherwise, if i_`x`` < `i_`y` is `true`, equivalent to:
458
+ ``` cpp
459
+ return -(y - x);
460
+ ```
461
+ - otherwise, equivalent to:
462
+ ``` cpp
463
+ return std::get<$i_x$>(x.it_) - std::get<$i_y$>(y.it_);
464
+ ```
465
+
466
+ ``` cpp
467
+ friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
468
+ requires see below;
469
+ ```
470
+
471
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` is `false`.
472
+
473
+ *Effects:* Let i_`x` denote `x.`*`it_`*`.index()`, d_`x` be
474
+ `ranges::distance(std::get<`i_`x``>(x.`*`it_`*`), ranges::end(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)))`.
475
+ Let s denote the sum of the sizes of all the ranges
476
+ `std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
477
+ the range \[i_`x`` + 1`, `sizeof...(Views)`) if there is any, and `0`
478
+ otherwise, of type difference_type, equivalent to:
479
+
480
+ ``` cpp
481
+ return -($d_x$ + s);
482
+ ```
483
+
484
+ *Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
485
+ except the first element, the expression in the *requires-clause* is
486
+ equivalent to:
487
+
488
+ ``` cpp
489
+ (sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
490
+ iterator_t<maybe-const<Const, Views>>> && ...) &&
491
+ (sized_range<maybe-const<Const, Fs>> && ...)
492
+ ```
493
+
494
+ ``` cpp
495
+ friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
496
+ requires see below;
497
+ ```
498
+
499
+ *Effects:* Equivalent to:
500
+
501
+ ``` cpp
502
+ return -(x - default_sentinel);
503
+ ```
504
+
505
+ *Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
506
+ except the first element, the expression in the *requires-clause* is
507
+ equivalent to:
508
+
509
+ ``` cpp
510
+ (sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
511
+ iterator_t<maybe-const<Const, Views>>> && ...) &&
512
+ (sized_range<maybe-const<Const, Fs>> && ...)
513
+ ```
514
+
515
+ ``` cpp
516
+ friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
517
+ ```
518
+
519
+ *Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
520
+
521
+ *Effects:* Equivalent to:
522
+
523
+ ``` cpp
524
+ return std::visit([](const auto& i)
525
+ -> concat-rvalue-reference-t<maybe-const<Const, Views>...> {
526
+ return ranges::iter_move(i);
527
+ },
528
+ it.it_);
529
+ ```
530
+
531
+ *Remarks:* The exception specification is equivalent to:
532
+
533
+ ``` cpp
534
+ ((is_nothrow_invocable_v<decltype(ranges::iter_move),
535
+ const iterator_t<maybe-const<Const, Views>>&> &&
536
+ is_nothrow_convertible_v<range_rvalue_reference_t<maybe-const<Const, Views>>,
537
+ concat-rvalue-reference-t<maybe-const<Const, Views>...>>) &&
538
+ ...)
539
+ ```
540
+
541
+ ``` cpp
542
+ friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
543
+ requires see below;
544
+ ```
545
+
546
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
547
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
548
+
549
+ *Effects:* Equivalent to:
550
+
551
+ ``` cpp
552
+ std::visit([&](const auto& it1, const auto& it2) {
553
+ if constexpr (is_same_v<decltype(it1), decltype(it2)>) {
554
+ ranges::iter_swap(it1, it2);
555
+ } else {
556
+ ranges::swap(*x, *y);
557
+ }
558
+ },
559
+ x.it_, y.it_);
560
+ ```
561
+
562
+ *Remarks:* The exception specification is equivalent to
563
+
564
+ ``` cpp
565
+ (noexcept(ranges::swap(*x, *y)) && ... && noexcept(ranges::iter_swap(its, its)))
566
+ ```
567
+
568
+ where `its` is a pack of lvalues of type
569
+ `const iterator_t<`*`maybe-const`*`<Const, Views>>` respectively.
570
+
571
+ The expression in the *requires-clause* is equivalent to
572
+
573
+ ``` cpp
574
+ swappable_with<iter_reference_t<iterator>, iter_reference_t<iterator>> &&
575
+ (... && indirectly_swappable<iterator_t<maybe-const<Const, Views>>>)
576
+ ```
577
+