From Jason Turner

[iterators.counted]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwzb1ezzl/{from.md → to.md} +389 -0
tmp/tmpwzb1ezzl/{from.md → to.md} RENAMED
@@ -0,0 +1,389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Counted iterators <a id="iterators.counted">[[iterators.counted]]</a>
2
+
3
+ #### Class template `counted_iterator` <a id="counted.iterator">[[counted.iterator]]</a>
4
+
5
+ Class template `counted_iterator` is an iterator adaptor with the same
6
+ behavior as the underlying iterator except that it keeps track of the
7
+ distance to the end of its range. It can be used together with
8
+ `default_sentinel` in calls to generic algorithms to operate on a range
9
+ of N elements starting at a given position without needing to know the
10
+ end position a priori.
11
+
12
+ [*Example 1*:
13
+
14
+ ``` cpp
15
+ list<string> s;
16
+ // populate the list s with at least 10 strings
17
+ vector<string> v;
18
+ // copies 10 strings into v:
19
+ ranges::copy(counted_iterator(s.begin(), 10), default_sentinel, back_inserter(v));
20
+ ```
21
+
22
+ — *end example*]
23
+
24
+ Two values `i1` and `i2` of types `counted_iterator<I1>` and
25
+ `counted_iterator<I2>` refer to elements of the same sequence if and
26
+ only if `next(i1.base(), i1.count())` and `next(i2.base(), i2.count())`
27
+ refer to the same (possibly past-the-end) element.
28
+
29
+ ``` cpp
30
+ namespace std {
31
+ template<input_or_output_iterator I>
32
+ class counted_iterator {
33
+ public:
34
+ using iterator_type = I;
35
+
36
+ constexpr counted_iterator() = default;
37
+ constexpr counted_iterator(I x, iter_difference_t<I> n);
38
+ template<class I2>
39
+ requires convertible_to<const I2&, I>
40
+ constexpr counted_iterator(const counted_iterator<I2>& x);
41
+
42
+ template<class I2>
43
+ requires assignable_from<I&, const I2&>
44
+ constexpr counted_iterator& operator=(const counted_iterator<I2>& x);
45
+
46
+ constexpr I base() const & requires copy_constructible<I>;
47
+ constexpr I base() &&;
48
+ constexpr iter_difference_t<I> count() const noexcept;
49
+ constexpr decltype(auto) operator*();
50
+ constexpr decltype(auto) operator*() const
51
+ requires dereferenceable<const I>;
52
+
53
+ constexpr counted_iterator& operator++();
54
+ decltype(auto) operator++(int);
55
+ constexpr counted_iterator operator++(int)
56
+ requires forward_iterator<I>;
57
+ constexpr counted_iterator& operator--()
58
+ requires bidirectional_iterator<I>;
59
+ constexpr counted_iterator operator--(int)
60
+ requires bidirectional_iterator<I>;
61
+
62
+ constexpr counted_iterator operator+(iter_difference_t<I> n) const
63
+ requires random_access_iterator<I>;
64
+ friend constexpr counted_iterator operator+(
65
+ iter_difference_t<I> n, const counted_iterator& x)
66
+ requires random_access_iterator<I>;
67
+ constexpr counted_iterator& operator+=(iter_difference_t<I> n)
68
+ requires random_access_iterator<I>;
69
+
70
+ constexpr counted_iterator operator-(iter_difference_t<I> n) const
71
+ requires random_access_iterator<I>;
72
+ template<common_with<I> I2>
73
+ friend constexpr iter_difference_t<I2> operator-(
74
+ const counted_iterator& x, const counted_iterator<I2>& y);
75
+ friend constexpr iter_difference_t<I> operator-(
76
+ const counted_iterator& x, default_sentinel_t);
77
+ friend constexpr iter_difference_t<I> operator-(
78
+ default_sentinel_t, const counted_iterator& y);
79
+ constexpr counted_iterator& operator-=(iter_difference_t<I> n)
80
+ requires random_access_iterator<I>;
81
+
82
+ constexpr decltype(auto) operator[](iter_difference_t<I> n) const
83
+ requires random_access_iterator<I>;
84
+
85
+ template<common_with<I> I2>
86
+ friend constexpr bool operator==(
87
+ const counted_iterator& x, const counted_iterator<I2>& y);
88
+ friend constexpr bool operator==(
89
+ const counted_iterator& x, default_sentinel_t);
90
+
91
+ template<common_with<I> I2>
92
+ friend constexpr strong_ordering operator<=>(
93
+ const counted_iterator& x, const counted_iterator<I2>& y);
94
+
95
+ friend constexpr iter_rvalue_reference_t<I> iter_move(const counted_iterator& i)
96
+ noexcept(noexcept(ranges::iter_move(i.current)))
97
+ requires input_iterator<I>;
98
+ template<indirectly_swappable<I> I2>
99
+ friend constexpr void iter_swap(const counted_iterator& x, const counted_iterator<I2>& y)
100
+ noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
101
+
102
+ private:
103
+ I current = I(); // exposition only
104
+ iter_difference_t<I> length = 0; // exposition only
105
+ };
106
+
107
+ template<class I>
108
+ struct incrementable_traits<counted_iterator<I>> {
109
+ using difference_type = iter_difference_t<I>;
110
+ };
111
+
112
+ template<input_iterator I>
113
+ struct iterator_traits<counted_iterator<I>> : iterator_traits<I> {
114
+ using pointer = void;
115
+ };
116
+ }
117
+ ```
118
+
119
+ #### Constructors and conversions <a id="counted.iter.const">[[counted.iter.const]]</a>
120
+
121
+ ``` cpp
122
+ constexpr counted_iterator(I i, iter_difference_t<I> n);
123
+ ```
124
+
125
+ *Preconditions:* `n >= 0`.
126
+
127
+ *Effects:* Initializes `current` with `std::move(i)` and `length` with
128
+ `n`.
129
+
130
+ ``` cpp
131
+ template<class I2>
132
+ requires convertible_to<const I2&, I>
133
+ constexpr counted_iterator(const counted_iterator<I2>& x);
134
+ ```
135
+
136
+ *Effects:* Initializes `current` with `x.current` and `length` with
137
+ `x.length`.
138
+
139
+ ``` cpp
140
+ template<class I2>
141
+ requires assignable_from<I&, const I2&>
142
+ constexpr counted_iterator& operator=(const counted_iterator<I2>& x);
143
+ ```
144
+
145
+ *Effects:* Assigns `x.current` to `current` and `x.length` to `length`.
146
+
147
+ *Returns:* `*this`.
148
+
149
+ #### Accessors <a id="counted.iter.access">[[counted.iter.access]]</a>
150
+
151
+ ``` cpp
152
+ constexpr I base() const & requires copy_constructible<I>;
153
+ ```
154
+
155
+ *Effects:* Equivalent to: `return current;`
156
+
157
+ ``` cpp
158
+ constexpr I base() &&;
159
+ ```
160
+
161
+ *Returns:* `std::move(current)`.
162
+
163
+ ``` cpp
164
+ constexpr iter_difference_t<I> count() const noexcept;
165
+ ```
166
+
167
+ *Effects:* Equivalent to: `return length;`
168
+
169
+ #### Element access <a id="counted.iter.elem">[[counted.iter.elem]]</a>
170
+
171
+ ``` cpp
172
+ constexpr decltype(auto) operator*();
173
+ constexpr decltype(auto) operator*() const
174
+ requires dereferenceable<const I>;
175
+ ```
176
+
177
+ *Effects:* Equivalent to: `return *current;`
178
+
179
+ ``` cpp
180
+ constexpr decltype(auto) operator[](iter_difference_t<I> n) const
181
+ requires random_access_iterator<I>;
182
+ ```
183
+
184
+ *Preconditions:* `n < length`.
185
+
186
+ *Effects:* Equivalent to: `return current[n];`
187
+
188
+ #### Navigation <a id="counted.iter.nav">[[counted.iter.nav]]</a>
189
+
190
+ ``` cpp
191
+ constexpr counted_iterator& operator++();
192
+ ```
193
+
194
+ *Preconditions:* `length > 0`.
195
+
196
+ *Effects:* Equivalent to:
197
+
198
+ ``` cpp
199
+ ++current;
200
+ --length;
201
+ return *this;
202
+ ```
203
+
204
+ ``` cpp
205
+ decltype(auto) operator++(int);
206
+ ```
207
+
208
+ *Preconditions:* `length > 0`.
209
+
210
+ *Effects:* Equivalent to:
211
+
212
+ ``` cpp
213
+ --length;
214
+ try { return current++; }
215
+ catch(...) { ++length; throw; }
216
+ ```
217
+
218
+ ``` cpp
219
+ constexpr counted_iterator operator++(int)
220
+ requires forward_iterator<I>;
221
+ ```
222
+
223
+ *Effects:* Equivalent to:
224
+
225
+ ``` cpp
226
+ counted_iterator tmp = *this;
227
+ ++*this;
228
+ return tmp;
229
+ ```
230
+
231
+ ``` cpp
232
+ constexpr counted_iterator& operator--()
233
+ requires bidirectional_iterator<I>;
234
+ ```
235
+
236
+ *Effects:* Equivalent to:
237
+
238
+ ``` cpp
239
+ --current;
240
+ ++length;
241
+ return *this;
242
+ ```
243
+
244
+ ``` cpp
245
+ constexpr counted_iterator operator--(int)
246
+ requires bidirectional_iterator<I>;
247
+ ```
248
+
249
+ *Effects:* Equivalent to:
250
+
251
+ ``` cpp
252
+ counted_iterator tmp = *this;
253
+ --*this;
254
+ return tmp;
255
+ ```
256
+
257
+ ``` cpp
258
+ constexpr counted_iterator operator+(iter_difference_t<I> n) const
259
+ requires random_access_iterator<I>;
260
+ ```
261
+
262
+ *Effects:* Equivalent to:
263
+ `return counted_iterator(current + n, length - n);`
264
+
265
+ ``` cpp
266
+ friend constexpr counted_iterator operator+(
267
+ iter_difference_t<I> n, const counted_iterator& x)
268
+ requires random_access_iterator<I>;
269
+ ```
270
+
271
+ *Effects:* Equivalent to: `return x + n;`
272
+
273
+ ``` cpp
274
+ constexpr counted_iterator& operator+=(iter_difference_t<I> n)
275
+ requires random_access_iterator<I>;
276
+ ```
277
+
278
+ *Preconditions:* `n <= length`.
279
+
280
+ *Effects:* Equivalent to:
281
+
282
+ ``` cpp
283
+ current += n;
284
+ length -= n;
285
+ return *this;
286
+ ```
287
+
288
+ ``` cpp
289
+ constexpr counted_iterator operator-(iter_difference_t<I> n) const
290
+ requires random_access_iterator<I>;
291
+ ```
292
+
293
+ *Effects:* Equivalent to:
294
+ `return counted_iterator(current - n, length + n);`
295
+
296
+ ``` cpp
297
+ template<common_with<I> I2>
298
+ friend constexpr iter_difference_t<I2> operator-(
299
+ const counted_iterator& x, const counted_iterator<I2>& y);
300
+ ```
301
+
302
+ *Preconditions:* `x` and `y` refer to elements of the same
303
+ sequence [[counted.iterator]].
304
+
305
+ *Effects:* Equivalent to: `return y.length - x.length;`
306
+
307
+ ``` cpp
308
+ friend constexpr iter_difference_t<I> operator-(
309
+ const counted_iterator& x, default_sentinel_t);
310
+ ```
311
+
312
+ *Effects:* Equivalent to: `return -x.length;`
313
+
314
+ ``` cpp
315
+ friend constexpr iter_difference_t<I> operator-(
316
+ default_sentinel_t, const counted_iterator& y);
317
+ ```
318
+
319
+ *Effects:* Equivalent to: `return y.length;`
320
+
321
+ ``` cpp
322
+ constexpr counted_iterator& operator-=(iter_difference_t<I> n)
323
+ requires random_access_iterator<I>;
324
+ ```
325
+
326
+ *Preconditions:* `-n <= length`.
327
+
328
+ *Effects:* Equivalent to:
329
+
330
+ ``` cpp
331
+ current -= n;
332
+ length += n;
333
+ return *this;
334
+ ```
335
+
336
+ #### Comparisons <a id="counted.iter.cmp">[[counted.iter.cmp]]</a>
337
+
338
+ ``` cpp
339
+ template<common_with<I> I2>
340
+ friend constexpr bool operator==(
341
+ const counted_iterator& x, const counted_iterator<I2>& y);
342
+ ```
343
+
344
+ *Preconditions:* `x` and `y` refer to elements of the same
345
+ sequence [[counted.iterator]].
346
+
347
+ *Effects:* Equivalent to: `return x.length == y.length;`
348
+
349
+ ``` cpp
350
+ friend constexpr bool operator==(
351
+ const counted_iterator& x, default_sentinel_t);
352
+ ```
353
+
354
+ *Effects:* Equivalent to: `return x.length == 0;`
355
+
356
+ ``` cpp
357
+ template<common_with<I> I2>
358
+ friend constexpr strong_ordering operator<=>(
359
+ const counted_iterator& x, const counted_iterator<I2>& y);
360
+ ```
361
+
362
+ *Preconditions:* `x` and `y` refer to elements of the same
363
+ sequence [[counted.iterator]].
364
+
365
+ *Effects:* Equivalent to: `return y.length <=> x.length;`
366
+
367
+ [*Note 1*: The argument order in the *Effects:* element is reversed
368
+ because `length` counts down, not up. — *end note*]
369
+
370
+ #### Customizations <a id="counted.iter.cust">[[counted.iter.cust]]</a>
371
+
372
+ ``` cpp
373
+ friend constexpr iter_rvalue_reference_t<I>
374
+ iter_move(const counted_iterator& i)
375
+ noexcept(noexcept(ranges::iter_move(i.current)))
376
+ requires input_iterator<I>;
377
+ ```
378
+
379
+ *Effects:* Equivalent to: `return ranges::iter_move(i.current);`
380
+
381
+ ``` cpp
382
+ template<indirectly_swappable<I> I2>
383
+ friend constexpr void
384
+ iter_swap(const counted_iterator& x, const counted_iterator<I2>& y)
385
+ noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
386
+ ```
387
+
388
+ *Effects:* Equivalent to `ranges::iter_swap(x.current, y.current)`.
389
+