From Jason Turner

[range.enumerate]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp0hgnm0o_/{from.md → to.md} +413 -0
tmp/tmp0hgnm0o_/{from.md → to.md} RENAMED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Enumerate view <a id="range.enumerate">[[range.enumerate]]</a>
2
+
3
+ #### Overview <a id="range.enumerate.overview">[[range.enumerate.overview]]</a>
4
+
5
+ `enumerate_view` is a view whose elements represent both the position
6
+ and value from a sequence of elements.
7
+
8
+ The name `views::enumerate` denotes a range adaptor object. Given a
9
+ subexpression `E`, the expression `views::enumerate(E)` is
10
+ expression-equivalent to
11
+ `enumerate_view<views::all_t<decltype((E))>>(E)`.
12
+
13
+ [*Example 1*:
14
+
15
+ ``` cpp
16
+ vector<int> vec{ 1, 2, 3 };
17
+ for (auto [index, value] : views::enumerate(vec))
18
+ cout << index << ":" << value << ' '; // prints 0:1 1:2 2:3
19
+ ```
20
+
21
+ — *end example*]
22
+
23
+ #### Class template `enumerate_view` <a id="range.enumerate.view">[[range.enumerate.view]]</a>
24
+
25
+ ``` cpp
26
+ namespace std::ranges {
27
+ template<view V>
28
+ requires range-with-movable-references<V>
29
+ class enumerate_view : public view_interface<enumerate_view<V>> {
30
+ V base_ = V(); // exposition only
31
+
32
+ // [range.enumerate.iterator], class template enumerate_view::iterator
33
+ template<bool Const>
34
+ class iterator; // exposition only
35
+
36
+ // [range.enumerate.sentinel], class template enumerate_view::sentinel
37
+ template<bool Const>
38
+ class sentinel; // exposition only
39
+
40
+ public:
41
+ constexpr enumerate_view() requires default_initializable<V> = default;
42
+ constexpr explicit enumerate_view(V base);
43
+
44
+ constexpr auto begin() requires (!simple-view<V>)
45
+ { return iterator<false>(ranges::begin(base_), 0); }
46
+ constexpr auto begin() const requires range-with-movable-references<const V>
47
+ { return iterator<true>(ranges::begin(base_), 0); }
48
+
49
+ constexpr auto end() requires (!simple-view<V>) {
50
+ if constexpr (common_range<V> && sized_range<V>)
51
+ return iterator<false>(ranges::end(base_), ranges::distance(base_));
52
+ else
53
+ return sentinel<false>(ranges::end(base_));
54
+ }
55
+ constexpr auto end() const requires range-with-movable-references<const V> {
56
+ if constexpr (common_range<const V> && sized_range<const V>)
57
+ return iterator<true>(ranges::end(base_), ranges::distance(base_));
58
+ else
59
+ return sentinel<true>(ranges::end(base_));
60
+ }
61
+
62
+ constexpr auto size() requires sized_range<V>
63
+ { return ranges::size(base_); }
64
+ constexpr auto size() const requires sized_range<const V>
65
+ { return ranges::size(base_); }
66
+
67
+ constexpr V base() const & requires copy_constructible<V> { return base_; }
68
+ constexpr V base() && { return std::move(base_); }
69
+ };
70
+
71
+ template<class R>
72
+ enumerate_view(R&&) -> enumerate_view<views::all_t<R>>;
73
+ }
74
+ ```
75
+
76
+ ``` cpp
77
+ constexpr explicit enumerate_view(V base);
78
+ ```
79
+
80
+ *Effects:* Initializes *base\_* with `std::move(base)`.
81
+
82
+ #### Class template `enumerate_view::iterator` <a id="range.enumerate.iterator">[[range.enumerate.iterator]]</a>
83
+
84
+ ``` cpp
85
+ namespace std::ranges {
86
+ template<view V>
87
+ requires range-with-movable-references<V>
88
+ template<bool Const>
89
+ class enumerate_view<V>::iterator {
90
+ using Base = maybe-const<Const, V>; // exposition only
91
+
92
+ public:
93
+ using iterator_category = input_iterator_tag;
94
+ using iterator_concept = see below;
95
+ using difference_type = range_difference_t<Base>;
96
+ using value_type = tuple<difference_type, range_value_t<Base>>;
97
+
98
+ private:
99
+ using reference-type = // exposition only
100
+ tuple<difference_type, range_reference_t<Base>>;
101
+ iterator_t<Base> current_ = iterator_t<Base>(); // exposition only
102
+ difference_type pos_ = 0; // exposition only
103
+
104
+ constexpr explicit
105
+ iterator(iterator_t<Base> current, difference_type pos); // exposition only
106
+
107
+ public:
108
+ iterator() requires default_initializable<iterator_t<Base>> = default;
109
+ constexpr iterator(iterator<!Const> i)
110
+ requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
111
+
112
+ constexpr const iterator_t<Base>& base() const & noexcept;
113
+ constexpr iterator_t<Base> base() &&;
114
+
115
+ constexpr difference_type index() const noexcept;
116
+
117
+ constexpr auto operator*() const {
118
+ return reference-type(pos_, *current_);
119
+ }
120
+
121
+ constexpr iterator& operator++();
122
+ constexpr void operator++(int);
123
+ constexpr iterator operator++(int) requires forward_range<Base>;
124
+
125
+ constexpr iterator& operator--() requires bidirectional_range<Base>;
126
+ constexpr iterator operator--(int) requires bidirectional_range<Base>;
127
+
128
+ constexpr iterator& operator+=(difference_type x)
129
+ requires random_access_range<Base>;
130
+ constexpr iterator& operator-=(difference_type x)
131
+ requires random_access_range<Base>;
132
+
133
+ constexpr auto operator[](difference_type n) const
134
+ requires random_access_range<Base>
135
+ { return reference-type(pos_ + n, current_[n]); }
136
+
137
+ friend constexpr bool operator==(const iterator& x, const iterator& y) noexcept;
138
+ friend constexpr strong_ordering operator<=>(const iterator& x, const iterator& y) noexcept;
139
+
140
+ friend constexpr iterator operator+(const iterator& x, difference_type y)
141
+ requires random_access_range<Base>;
142
+ friend constexpr iterator operator+(difference_type x, const iterator& y)
143
+ requires random_access_range<Base>;
144
+ friend constexpr iterator operator-(const iterator& x, difference_type y)
145
+ requires random_access_range<Base>;
146
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y);
147
+
148
+ friend constexpr auto iter_move(const iterator& i)
149
+ noexcept(noexcept(ranges::iter_move(i.current_)) &&
150
+ is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {
151
+ return tuple<difference_type,
152
+ range_rvalue_reference_t<Base>>(i.pos_, ranges::iter_move(i.current_));
153
+ }
154
+ };
155
+ }
156
+ ```
157
+
158
+ The member *typedef-name* `iterator::iterator_concept` is defined as
159
+ follows:
160
+
161
+ - If *`Base`* models `random_access_range`, then `iterator_concept`
162
+ denotes `random_access_iterator_tag`.
163
+ - Otherwise, if *`Base`* models `bidirectional_range`, then
164
+ `iterator_concept` denotes `bidirectional_iterator_tag`.
165
+ - Otherwise, if *`Base`* models `forward_range`, then `iterator_concept`
166
+ denotes `forward_iterator_tag`.
167
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
168
+
169
+ ``` cpp
170
+ constexpr explicit iterator(iterator_t<Base> current, difference_type pos);
171
+ ```
172
+
173
+ *Effects:* Initializes *current\_* with `std::move(current)` and *pos\_*
174
+ with `pos`.
175
+
176
+ ``` cpp
177
+ constexpr iterator(iterator<!Const> i)
178
+ requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
179
+ ```
180
+
181
+ *Effects:* Initializes *current\_* with `std::move(i.`*`current_`*`)`
182
+ and *pos\_* with `i.`*`pos_`*.
183
+
184
+ ``` cpp
185
+ constexpr const iterator_t<Base>& base() const & noexcept;
186
+ ```
187
+
188
+ *Effects:* Equivalent to: `return `*`current_`*`;`
189
+
190
+ ``` cpp
191
+ constexpr iterator_t<Base> base() &&;
192
+ ```
193
+
194
+ *Effects:* Equivalent to: `return std::move(`*`current_`*`);`
195
+
196
+ ``` cpp
197
+ constexpr difference_type index() const noexcept;
198
+ ```
199
+
200
+ *Effects:* Equivalent to: `return `*`pos_`*`;`
201
+
202
+ ``` cpp
203
+ constexpr iterator& operator++();
204
+ ```
205
+
206
+ *Effects:* Equivalent to:
207
+
208
+ ``` cpp
209
+ ++current_;
210
+ ++pos_;
211
+ return *this;
212
+ ```
213
+
214
+ ``` cpp
215
+ constexpr void operator++(int);
216
+ ```
217
+
218
+ *Effects:* Equivalent to `++*this`.
219
+
220
+ ``` cpp
221
+ constexpr iterator operator++(int) requires forward_range<Base>;
222
+ ```
223
+
224
+ *Effects:* Equivalent to:
225
+
226
+ ``` cpp
227
+ auto temp = *this;
228
+ ++*this;
229
+ return temp;
230
+ ```
231
+
232
+ ``` cpp
233
+ constexpr iterator& operator--() requires bidirectional_range<Base>;
234
+ ```
235
+
236
+ *Effects:* Equivalent to:
237
+
238
+ ``` cpp
239
+ --current_;
240
+ --pos_;
241
+ return *this;
242
+ ```
243
+
244
+ ``` cpp
245
+ constexpr iterator operator--(int) requires bidirectional_range<Base>;
246
+ ```
247
+
248
+ *Effects:* Equivalent to:
249
+
250
+ ``` cpp
251
+ auto temp = *this;
252
+ --*this;
253
+ return temp;
254
+ ```
255
+
256
+ ``` cpp
257
+ constexpr iterator& operator+=(difference_type n)
258
+ requires random_access_range<Base>;
259
+ ```
260
+
261
+ *Effects:* Equivalent to:
262
+
263
+ ``` cpp
264
+ current_ += n;
265
+ pos_ += n;
266
+ return *this;
267
+ ```
268
+
269
+ ``` cpp
270
+ constexpr iterator& operator-=(difference_type n)
271
+ requires random_access_range<Base>;
272
+ ```
273
+
274
+ *Effects:* Equivalent to:
275
+
276
+ ``` cpp
277
+ current_ -= n;
278
+ pos_ -= n;
279
+ return *this;
280
+ ```
281
+
282
+ ``` cpp
283
+ friend constexpr bool operator==(const iterator& x, const iterator& y) noexcept;
284
+ ```
285
+
286
+ *Effects:* Equivalent to: `return x.`*`pos_`*` == y.`*`pos_`*`;`
287
+
288
+ ``` cpp
289
+ friend constexpr strong_ordering operator<=>(const iterator& x, const iterator& y) noexcept;
290
+ ```
291
+
292
+ *Effects:* Equivalent to: `return x.`*`pos_`*` <=> y.`*`pos_`*`;`
293
+
294
+ ``` cpp
295
+ friend constexpr iterator operator+(const iterator& x, difference_type y)
296
+ requires random_access_range<Base>;
297
+ ```
298
+
299
+ *Effects:* Equivalent to:
300
+
301
+ ``` cpp
302
+ auto temp = x;
303
+ temp += y;
304
+ return temp;
305
+ ```
306
+
307
+ ``` cpp
308
+ friend constexpr iterator operator+(difference_type x, const iterator& y)
309
+ requires random_access_range<Base>;
310
+ ```
311
+
312
+ *Effects:* Equivalent to: `return y + x;`
313
+
314
+ ``` cpp
315
+ friend constexpr iterator operator-(const iterator& x, difference_type y)
316
+ requires random_access_range<Base>;
317
+ ```
318
+
319
+ *Effects:* Equivalent to:
320
+
321
+ ``` cpp
322
+ auto temp = x;
323
+ temp -= y;
324
+ return temp;
325
+ ```
326
+
327
+ ``` cpp
328
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y);
329
+ ```
330
+
331
+ *Effects:* Equivalent to: `return x.`*`pos_`*` - y.`*`pos_`*`;`
332
+
333
+ #### Class template `enumerate_view::sentinel` <a id="range.enumerate.sentinel">[[range.enumerate.sentinel]]</a>
334
+
335
+ ``` cpp
336
+ namespace std::ranges {
337
+ template<view V>
338
+ requires range-with-movable-references<V>
339
+ template<bool Const>
340
+ class enumerate_view<V>::sentinel {
341
+ using Base = maybe-const<Const, V>; // exposition only
342
+ sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
343
+ constexpr explicit sentinel(sentinel_t<Base> end); // exposition only
344
+
345
+ public:
346
+ sentinel() = default;
347
+ constexpr sentinel(sentinel<!Const> other)
348
+ requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
349
+
350
+ constexpr sentinel_t<Base> base() const;
351
+
352
+ template<bool OtherConst>
353
+ requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
354
+ friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
355
+
356
+ template<bool OtherConst>
357
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
358
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
359
+ operator-(const iterator<OtherConst>& x, const sentinel& y);
360
+
361
+ template<bool OtherConst>
362
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
363
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
364
+ operator-(const sentinel& x, const iterator<OtherConst>& y);
365
+ };
366
+ }
367
+ ```
368
+
369
+ ``` cpp
370
+ constexpr explicit sentinel(sentinel_t<Base> end);
371
+ ```
372
+
373
+ *Effects:* Initializes *end\_* with `std::move(end)`.
374
+
375
+ ``` cpp
376
+ constexpr sentinel(sentinel<!Const> other)
377
+ requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
378
+ ```
379
+
380
+ *Effects:* Initializes *end\_* with `std::move(other.`*`end_`*`)`.
381
+
382
+ ``` cpp
383
+ constexpr sentinel_t<Base> base() const;
384
+ ```
385
+
386
+ *Effects:* Equivalent to: `return `*`end_`*`;`
387
+
388
+ ``` cpp
389
+ template<bool OtherConst>
390
+ requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
391
+ friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
392
+ ```
393
+
394
+ *Effects:* Equivalent to: `return x.`*`current_`*` == y.`*`end_`*`;`
395
+
396
+ ``` cpp
397
+ template<bool OtherConst>
398
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
399
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
400
+ operator-(const iterator<OtherConst>& x, const sentinel& y);
401
+ ```
402
+
403
+ *Effects:* Equivalent to: `return x.`*`current_`*` - y.`*`end_`*`;`
404
+
405
+ ``` cpp
406
+ template<bool OtherConst>
407
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
408
+ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
409
+ operator-(const sentinel& x, const iterator<OtherConst>& y);
410
+ ```
411
+
412
+ *Effects:* Equivalent to: `return x.`*`end_`*` - y.`*`current_`*`;`
413
+