From Jason Turner

[range.cartesian.iterator]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpl62k_noj/{from.md → to.md} +399 -0
tmp/tmpl62k_noj/{from.md → to.md} RENAMED
@@ -0,0 +1,399 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Class template `cartesian_product_view::iterator` <a id="range.cartesian.iterator">[[range.cartesian.iterator]]</a>
2
+
3
+ ``` cpp
4
+ namespace std::ranges {
5
+ template<input_range First, forward_range... Vs>
6
+ requires (view<First> && ... && view<Vs>)
7
+ template<bool Const>
8
+ class cartesian_product_view<First, Vs...>::iterator {
9
+ public:
10
+ using iterator_category = input_iterator_tag;
11
+ using iterator_concept = see below;
12
+ using value_type = tuple<range_value_t<maybe-const<Const, First>>,
13
+ range_value_t<maybe-const<Const, Vs>>...>;
14
+ using reference = tuple<range_reference_t<maybe-const<Const, First>>,
15
+ range_reference_t<maybe-const<Const, Vs>>...>;
16
+ using difference_type = see below;
17
+
18
+ iterator() = default;
19
+
20
+ constexpr iterator(iterator<!Const> i) requires Const &&
21
+ (convertible_to<iterator_t<First>, iterator_t<const First>> &&
22
+ ... && convertible_to<iterator_t<Vs>, iterator_t<const Vs>>);
23
+
24
+ constexpr auto operator*() const;
25
+ constexpr iterator& operator++();
26
+ constexpr void operator++(int);
27
+ constexpr iterator operator++(int) requires forward_range<maybe-const<Const, First>>;
28
+
29
+ constexpr iterator& operator--()
30
+ requires cartesian-product-is-bidirectional<Const, First, Vs...>;
31
+ constexpr iterator operator--(int)
32
+ requires cartesian-product-is-bidirectional<Const, First, Vs...>;
33
+
34
+ constexpr iterator& operator+=(difference_type x)
35
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
36
+ constexpr iterator& operator-=(difference_type x)
37
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
38
+
39
+ constexpr reference operator[](difference_type n) const
40
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
41
+
42
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
43
+ requires equality_comparable<iterator_t<maybe-const<Const, First>>>;
44
+
45
+ friend constexpr bool operator==(const iterator& x, default_sentinel_t);
46
+
47
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
48
+ requires all-random-access<Const, First, Vs...>;
49
+
50
+ friend constexpr iterator operator+(const iterator& x, difference_type y)
51
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
52
+ friend constexpr iterator operator+(difference_type x, const iterator& y)
53
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
54
+ friend constexpr iterator operator-(const iterator& x, difference_type y)
55
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
56
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
57
+ requires cartesian-is-sized-sentinel<Const, iterator_t, First, Vs...>;
58
+
59
+ friend constexpr difference_type operator-(const iterator& i, default_sentinel_t)
60
+ requires cartesian-is-sized-sentinel<Const, sentinel_t, First, Vs...>;
61
+ friend constexpr difference_type operator-(default_sentinel_t, const iterator& i)
62
+ requires cartesian-is-sized-sentinel<Const, sentinel_t, First, Vs...>;
63
+
64
+ friend constexpr auto iter_move(const iterator& i) noexcept(see below);
65
+
66
+ friend constexpr void iter_swap(const iterator& l, const iterator& r) noexcept(see below)
67
+ requires (indirectly_swappable<iterator_t<maybe-const<Const, First>>> && ... &&
68
+ indirectly_swappable<iterator_t<maybe-const<Const, Vs>>>);
69
+
70
+ private:
71
+ using Parent = maybe-const<Const, cartesian_product_view>; // exposition only
72
+ Parent* parent_ = nullptr; // exposition only
73
+ tuple<iterator_t<maybe-const<Const, First>>,
74
+ iterator_t<maybe-const<Const, Vs>>...> current_; // exposition only
75
+
76
+ template<size_t N = sizeof...(Vs)>
77
+ constexpr void next(); // exposition only
78
+
79
+ template<size_t N = sizeof...(Vs)>
80
+ constexpr void prev(); // exposition only
81
+
82
+ template<class Tuple>
83
+ constexpr difference_type distance-from(const Tuple& t) const; // exposition only
84
+
85
+ constexpr iterator(Parent& parent, tuple<iterator_t<maybe-const<Const, First>>,
86
+ iterator_t<maybe-const<Const, Vs>>...> current); // exposition only
87
+ };
88
+ }
89
+ ```
90
+
91
+ `iterator::iterator_concept` is defined as follows:
92
+
93
+ - If `cartesian-product-is-random-access<Const, First, Vs...>` is
94
+ modeled, then `iterator_concept` denotes `random_access_iterator_tag`.
95
+ - Otherwise, if
96
+ `cartesian-product-is-bidirectional<Const, First, Vs...>` is modeled,
97
+ then `iterator_concept` denotes `bidirectional_iterator_tag`.
98
+ - Otherwise, if `maybe-const<Const, First>` models `forward_range`, then
99
+ `iterator_concept` denotes `forward_iterator_tag`.
100
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
101
+
102
+ `iterator::difference_type` is an *implementation-defined*
103
+ signed-integer-like type.
104
+
105
+ *Recommended practice:* `iterator::difference_type` should be the
106
+ smallest signed-integer-like type that is sufficiently wide to store the
107
+ product of the maximum sizes of all underlying ranges if such a type
108
+ exists.
109
+
110
+ ``` cpp
111
+ template<size_t N = sizeof...(Vs)>
112
+ constexpr void next();
113
+ ```
114
+
115
+ *Effects:* Equivalent to:
116
+
117
+ ``` cpp
118
+ auto& it = std::get<N>(current_);
119
+ ++it;
120
+ if constexpr (N > 0) {
121
+ if (it == ranges::end(std::get<N>(parent_->bases_))) {
122
+ it = ranges::begin(std::get<N>(parent_->bases_));
123
+ next<N - 1>();
124
+ }
125
+ }
126
+ ```
127
+
128
+ ``` cpp
129
+ template<size_t N = sizeof...(Vs)>
130
+ constexpr void prev();
131
+ ```
132
+
133
+ *Effects:* Equivalent to:
134
+
135
+ ``` cpp
136
+ auto& it = std::get<N>(current_);
137
+ if constexpr (N > 0) {
138
+ if (it == ranges::begin(std::get<N>(parent_->bases_))) {
139
+ it = cartesian-common-arg-end(std::get<N>(parent_->bases_));
140
+ prev<N - 1>();
141
+ }
142
+ }
143
+ --it;
144
+ ```
145
+
146
+ ``` cpp
147
+ template<class Tuple>
148
+ constexpr difference_type distance-from(const Tuple& t) const;
149
+ ```
150
+
151
+ Let:
152
+
153
+ - scaled-size(N) be the product of
154
+ `static_cast<difference_type>(ranges::size(std::get<`N`>(`*`parent_`*`->`*`bases_`*`)))`
155
+ and scaled-size(N+1) if N ≤ `sizeof...(Vs)`, otherwise
156
+ `static_cast<difference_type>(1)`;
157
+ - scaled-distance(N) be the product of
158
+ `static_cast<difference_type>(std::get<`N`>(`*`current_`*`) - std::get<`N`>(t))`
159
+ and scaled-size(N+1); and
160
+ - *scaled-sum* be the sum of scaled-distance(N) for every integer
161
+ 0 ≤ N ≤ `sizeof...(Vs)`.
162
+
163
+ *Preconditions:* *scaled-sum* can be represented by `difference_type`.
164
+
165
+ *Returns:* *scaled-sum*.
166
+
167
+ ``` cpp
168
+ constexpr iterator(Parent& parent, tuple<iterator_t<maybe-const<Const, First>>,
169
+ iterator_t<maybe-const<Const, Vs>>...> current);
170
+ ```
171
+
172
+ *Effects:* Initializes *parent\_* with `addressof(parent)` and
173
+ *current\_* with `std::move(current)`.
174
+
175
+ ``` cpp
176
+ constexpr iterator(iterator<!Const> i) requires Const &&
177
+ (convertible_to<iterator_t<First>, iterator_t<const First>> &&
178
+ ... && convertible_to<iterator_t<Vs>, iterator_t<const Vs>>);
179
+ ```
180
+
181
+ *Effects:* Initializes *parent\_* with `i.`*`parent_`* and *current\_*
182
+ with `std::move(i.`*`current_`*`)`.
183
+
184
+ ``` cpp
185
+ constexpr auto operator*() const;
186
+ ```
187
+
188
+ *Effects:* Equivalent to:
189
+
190
+ ``` cpp
191
+ return tuple-transform([](auto& i) -> decltype(auto) { return *i; }, current_);
192
+ ```
193
+
194
+ ``` cpp
195
+ constexpr iterator& operator++();
196
+ ```
197
+
198
+ *Effects:* Equivalent to:
199
+
200
+ ``` cpp
201
+ next();
202
+ return *this;
203
+ ```
204
+
205
+ ``` cpp
206
+ constexpr void operator++(int);
207
+ ```
208
+
209
+ *Effects:* Equivalent to `++*this`.
210
+
211
+ ``` cpp
212
+ constexpr iterator operator++(int) requires forward_range<maybe-const<Const, First>>;
213
+ ```
214
+
215
+ *Effects:* Equivalent to:
216
+
217
+ ``` cpp
218
+ auto tmp = *this;
219
+ ++*this;
220
+ return tmp;
221
+ ```
222
+
223
+ ``` cpp
224
+ constexpr iterator& operator--()
225
+ requires cartesian-product-is-bidirectional<Const, First, Vs...>;
226
+ ```
227
+
228
+ *Effects:* Equivalent to:
229
+
230
+ ``` cpp
231
+ prev();
232
+ return *this;
233
+ ```
234
+
235
+ ``` cpp
236
+ constexpr iterator operator--(int)
237
+ requires cartesian-product-is-bidirectional<Const, First, Vs...>;
238
+ ```
239
+
240
+ *Effects:* Equivalent to:
241
+
242
+ ``` cpp
243
+ auto tmp = *this;
244
+ --*this;
245
+ return tmp;
246
+ ```
247
+
248
+ ``` cpp
249
+ constexpr iterator& operator+=(difference_type x)
250
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
251
+ ```
252
+
253
+ Let `orig` be the value of `*this` before the call.
254
+
255
+ Let `ret` be:
256
+
257
+ - If `x > 0`, the value of `*this` had *next* been called `x` times.
258
+ - Otherwise, if `x < 0`, the value of `*this` had *prev* been called
259
+ `-x` times.
260
+ - Otherwise, `orig`.
261
+
262
+ *Preconditions:* `x` is in the range
263
+ $[\texttt{ranges::distance(*this, ranges::begin(*\textit{parent_}))},$
264
+ $\texttt{ranges::distance(*this, ranges::end(*\textit{parent_}))}]$.
265
+
266
+ *Effects:* Sets the value of `*this` to `ret`.
267
+
268
+ *Returns:* `*this`.
269
+
270
+ *Complexity:* Constant.
271
+
272
+ ``` cpp
273
+ constexpr iterator& operator-=(difference_type x)
274
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
275
+ ```
276
+
277
+ *Effects:* Equivalent to:
278
+
279
+ ``` cpp
280
+ *this += -x;
281
+ return *this;
282
+ ```
283
+
284
+ ``` cpp
285
+ constexpr reference operator[](difference_type n) const
286
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
287
+ ```
288
+
289
+ *Effects:* Equivalent to: `return *((*this) + n);`
290
+
291
+ ``` cpp
292
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
293
+ requires equality_comparable<iterator_t<maybe-const<Const, First>>>;
294
+ ```
295
+
296
+ *Effects:* Equivalent to: `return x.`*`current_`*` == y.`*`current_`*`;`
297
+
298
+ ``` cpp
299
+ friend constexpr bool operator==(const iterator& x, default_sentinel_t);
300
+ ```
301
+
302
+ *Returns:* `true` if
303
+ `std::get<`i`>(x.`*`current_`*`) == ranges::end(std::get<`i`>(x.`*`parent_`*`->`*`bases_`*`))`
304
+ is `true` for any integer 0 ≤ i ≤ `sizeof...(Vs)`; otherwise, `false`.
305
+
306
+ ``` cpp
307
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
308
+ requires all-random-access<Const, First, Vs...>;
309
+ ```
310
+
311
+ *Effects:* Equivalent to:
312
+ `return x.`*`current_`*` <=> y.`*`current_`*`;`
313
+
314
+ ``` cpp
315
+ friend constexpr iterator operator+(const iterator& x, difference_type y)
316
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
317
+ ```
318
+
319
+ *Effects:* Equivalent to: `return `*`iterator`*`(x) += y;`
320
+
321
+ ``` cpp
322
+ friend constexpr iterator operator+(difference_type x, const iterator& y)
323
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
324
+ ```
325
+
326
+ *Effects:* Equivalent to: `return y + x;`
327
+
328
+ ``` cpp
329
+ friend constexpr iterator operator-(const iterator& x, difference_type y)
330
+ requires cartesian-product-is-random-access<Const, First, Vs...>;
331
+ ```
332
+
333
+ *Effects:* Equivalent to: `return `*`iterator`*`(x) -= y;`
334
+
335
+ ``` cpp
336
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
337
+ requires cartesian-is-sized-sentinel<Const, iterator_t, First, Vs...>;
338
+ ```
339
+
340
+ *Effects:* Equivalent to:
341
+ `return x.`*`distance-from`*`(y.`*`current_`*`);`
342
+
343
+ ``` cpp
344
+ friend constexpr difference_type operator-(const iterator& i, default_sentinel_t)
345
+ requires cartesian-is-sized-sentinel<Const, sentinel_t, First, Vs...>;
346
+ ```
347
+
348
+ Let *end-tuple* be an object of a type that is a specialization of
349
+ `tuple`, such that:
350
+
351
+ - `std::get<0>(`*`end-tuple`*`)` has the same value as
352
+ `ranges::end(std::get<0>(i.`*`parent_`*`->`*`bases_`*`))`;
353
+ - `std::get<`N`>(`*`end-tuple`*`)` has the same value as
354
+ `ranges::begin(std::get<`N`>(i.`*`parent_`*`->`*`bases_`*`))` for
355
+ every integer 1 ≤ N ≤ `sizeof...(Vs)`.
356
+
357
+ *Effects:* Equivalent to:
358
+ `return i.`*`distance-from`*`(`*`end-tuple`*`);`
359
+
360
+ ``` cpp
361
+ friend constexpr difference_type operator-(default_sentinel_t s, const iterator& i)
362
+ requires cartesian-is-sized-sentinel<Const, sentinel_t, First, Vs...>;
363
+ ```
364
+
365
+ *Effects:* Equivalent to: `return -(i - s);`
366
+
367
+ ``` cpp
368
+ friend constexpr auto iter_move(const iterator& i) noexcept(see below);
369
+ ```
370
+
371
+ *Effects:* Equivalent to:
372
+ `return `*`tuple-transform`*`(ranges::iter_move, i.`*`current_`*`);`
373
+
374
+ *Remarks:* The exception specification is equivalent to the logical of
375
+ the following expressions:
376
+
377
+ - `noexcept(ranges::iter_move(std::get<`N`>(i.`*`current_`*`)))` for
378
+ every integer 0 ≤ N ≤ `sizeof...(Vs)`,
379
+ - `is_nothrow_move_constructible_v<range_rvalue_reference_t<`*`maybe-const`*`<Const, T>>>`
380
+ for every type `T` in `First, Vs...`.
381
+
382
+ ``` cpp
383
+ friend constexpr void iter_swap(const iterator& l, const iterator& r) noexcept(see below)
384
+ requires (indirectly_swappable<iterator_t<maybe-const<Const, First>>> && ... &&
385
+ indirectly_swappable<iterator_t<maybe-const<Const, Vs>>>);
386
+ ```
387
+
388
+ *Effects:* For every integer 0 ≤ i ≤ `sizeof...(Vs)`, performs:
389
+
390
+ ``` cpp
391
+ ranges::iter_swap(std::get<i>(l.current_), std::get<i>(r.current_))
392
+ ```
393
+
394
+ *Remarks:* The exception specification is equivalent to the logical of
395
+ the following expressions:
396
+
397
+ - `noexcept(ranges::iter_swap(std::get<`i`>(l.`*`current_`*`), std::get<`i`>(r.`*`current_`*`)))`
398
+ for every integer 0 ≤ i ≤ `sizeof...(Vs)`.
399
+