From Jason Turner

[iterator.primitives]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp56etsb1v/{from.md → to.md} +204 -121
tmp/tmp56etsb1v/{from.md → to.md} RENAMED
@@ -1,131 +1,33 @@
1
  ## Iterator primitives <a id="iterator.primitives">[[iterator.primitives]]</a>
2
 
3
- To simplify the task of defining iterators, the library provides several
4
- classes and functions:
5
-
6
- ### Iterator traits <a id="iterator.traits">[[iterator.traits]]</a>
7
-
8
- To implement algorithms only in terms of iterators, it is often
9
- necessary to determine the value and difference types that correspond to
10
- a particular iterator type. Accordingly, it is required that if
11
- `Iterator` is the type of an iterator, the types
12
-
13
- ``` cpp
14
- iterator_traits<Iterator>::difference_type
15
- iterator_traits<Iterator>::value_type
16
- iterator_traits<Iterator>::iterator_category
17
- ```
18
-
19
- be defined as the iterator’s difference type, value type and iterator
20
- category, respectively. In addition, the types
21
-
22
- ``` cpp
23
- iterator_traits<Iterator>::reference
24
- iterator_traits<Iterator>::pointer
25
- ```
26
-
27
- shall be defined as the iterator’s reference and pointer types, that is,
28
- for an iterator object `a`, the same type as the type of `*a` and `a->`,
29
- respectively. In the case of an output iterator, the types
30
-
31
- ``` cpp
32
- iterator_traits<Iterator>::difference_type
33
- iterator_traits<Iterator>::value_type
34
- iterator_traits<Iterator>::reference
35
- iterator_traits<Iterator>::pointer
36
- ```
37
-
38
- may be defined as `void`.
39
-
40
- If `Iterator` has valid ([[temp.deduct]]) member types
41
- `difference_type`, `value_type`, `pointer`, `reference`, and
42
- `iterator_category`, `iterator_traits<Iterator>` shall have the
43
- following as publicly accessible members:
44
-
45
- ``` cpp
46
- using difference_type = typename Iterator::difference_type;
47
- using value_type = typename Iterator::value_type;
48
- using pointer = typename Iterator::pointer;
49
- using reference = typename Iterator::reference;
50
- using iterator_category = typename Iterator::iterator_category;
51
- ```
52
-
53
- Otherwise, `iterator_traits<Iterator>` shall have no members by any of
54
- the above names.
55
-
56
- It is specialized for pointers as
57
-
58
- ``` cpp
59
- namespace std {
60
- template<class T> struct iterator_traits<T*> {
61
- using difference_type = ptrdiff_t;
62
- using value_type = T;
63
- using pointer = T*;
64
- using reference = T&;
65
- using iterator_category = random_access_iterator_tag;
66
- };
67
- }
68
- ```
69
-
70
- and for pointers to const as
71
-
72
- ``` cpp
73
- namespace std {
74
- template<class T> struct iterator_traits<const T*> {
75
- using difference_type = ptrdiff_t;
76
- using value_type = T;
77
- using pointer = const T*;
78
- using reference = const T&;
79
- using iterator_category = random_access_iterator_tag;
80
- };
81
- }
82
- ```
83
-
84
- [*Example 1*:
85
-
86
- To implement a generic `reverse` function, a C++program can do the
87
- following:
88
-
89
- ``` cpp
90
- template <class BidirectionalIterator>
91
- void reverse(BidirectionalIterator first, BidirectionalIterator last) {
92
- typename iterator_traits<BidirectionalIterator>::difference_type n =
93
- distance(first, last);
94
- --n;
95
- while(n > 0) {
96
- typename iterator_traits<BidirectionalIterator>::value_type
97
- tmp = *first;
98
- *first++ = *--last;
99
- *last = tmp;
100
- n -= 2;
101
- }
102
- }
103
- ```
104
-
105
- — *end example*]
106
 
107
  ### Standard iterator tags <a id="std.iterator.tags">[[std.iterator.tags]]</a>
108
 
109
  It is often desirable for a function template specialization to find out
110
  what is the most specific category of its iterator argument, so that the
111
  function can select the most efficient algorithm at compile time. To
112
  facilitate this, the library introduces *category tag* classes which are
113
  used as compile time tags for algorithm selection. They are:
114
- `input_iterator_tag`, `output_iterator_tag`, `forward_iterator_tag`,
115
- `bidirectional_iterator_tag` and `random_access_iterator_tag`. For every
116
- iterator of type `Iterator`,
117
- `iterator_traits<Iterator>::iterator_category` shall be defined to be
118
- the most specific category tag that describes the iterator’s behavior.
 
 
119
 
120
  ``` cpp
121
  namespace std {
122
- struct input_iterator_tag { };
123
  struct output_iterator_tag { };
 
124
  struct forward_iterator_tag: public input_iterator_tag { };
125
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
126
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };
 
127
  }
128
  ```
129
 
130
  [*Example 1*:
131
 
@@ -145,11 +47,11 @@ template<class T> struct iterator_traits<BinaryTreeIterator<T>> {
145
 
146
  — *end example*]
147
 
148
  [*Example 2*:
149
 
150
- If `evolve()` is well defined for bidirectional iterators, but can be
151
  implemented more efficiently for random access iterators, then the
152
  implementation is as follows:
153
 
154
  ``` cpp
155
  template<class BidirectionalIterator>
@@ -185,31 +87,29 @@ iterators they use `++` to provide linear time implementations.
185
  ``` cpp
186
  template<class InputIterator, class Distance>
187
  constexpr void advance(InputIterator& i, Distance n);
188
  ```
189
 
190
- *Requires:* `n` shall be negative only for bidirectional and random
191
- access iterators.
192
 
193
- *Effects:* Increments (or decrements for negative `n`) iterator
194
- reference `i` by `n`.
195
 
196
  ``` cpp
197
  template<class InputIterator>
198
  constexpr typename iterator_traits<InputIterator>::difference_type
199
  distance(InputIterator first, InputIterator last);
200
  ```
201
 
202
- *Effects:* If `InputIterator` meets the requirements of random access
203
- iterator, returns `(last - first)`; otherwise, returns the number of
 
 
 
 
204
  increments needed to get from `first` to `last`.
205
 
206
- *Requires:* If `InputIterator` meets the requirements of random access
207
- iterator, `last` shall be reachable from `first` or `first` shall be
208
- reachable from `last`; otherwise, `last` shall be reachable from
209
- `first`.
210
-
211
  ``` cpp
212
  template<class InputIterator>
213
  constexpr InputIterator next(InputIterator x,
214
  typename iterator_traits<InputIterator>::difference_type n = 1);
215
  ```
@@ -222,5 +122,188 @@ template <class BidirectionalIterator>
222
  typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
223
  ```
224
 
225
  *Effects:* Equivalent to: `advance(x, -n); return x;`
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ## Iterator primitives <a id="iterator.primitives">[[iterator.primitives]]</a>
2
 
3
+ To simplify the use of iterators, the library provides several classes
4
+ and functions.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  ### Standard iterator tags <a id="std.iterator.tags">[[std.iterator.tags]]</a>
7
 
8
  It is often desirable for a function template specialization to find out
9
  what is the most specific category of its iterator argument, so that the
10
  function can select the most efficient algorithm at compile time. To
11
  facilitate this, the library introduces *category tag* classes which are
12
  used as compile time tags for algorithm selection. They are:
13
+ `output_iterator_tag`, `input_iterator_tag`, `forward_iterator_tag`,
14
+ `bidirectional_iterator_tag`, `random_access_iterator_tag`, and
15
+ `contiguous_iterator_tag`. For every iterator of type `I`,
16
+ `iterator_traits<I>::iterator_category` shall be defined to be a
17
+ category tag that describes the iterator’s behavior. Additionally,
18
+ `iterator_traits<I>::iterator_concept` may be used to indicate
19
+ conformance to the iterator concepts [[iterator.concepts]].
20
 
21
  ``` cpp
22
  namespace std {
 
23
  struct output_iterator_tag { };
24
+ struct input_iterator_tag { };
25
  struct forward_iterator_tag: public input_iterator_tag { };
26
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
27
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };
28
+ struct contiguous_iterator_tag: public random_access_iterator_tag { };
29
  }
30
  ```
31
 
32
  [*Example 1*:
33
 
 
47
 
48
  — *end example*]
49
 
50
  [*Example 2*:
51
 
52
+ If `evolve()` is well-defined for bidirectional iterators, but can be
53
  implemented more efficiently for random access iterators, then the
54
  implementation is as follows:
55
 
56
  ``` cpp
57
  template<class BidirectionalIterator>
 
87
  ``` cpp
88
  template<class InputIterator, class Distance>
89
  constexpr void advance(InputIterator& i, Distance n);
90
  ```
91
 
92
+ *Preconditions:* `n` is negative only for bidirectional iterators.
 
93
 
94
+ *Effects:* Increments `i` by `n` if `n` is non-negative, and decrements
95
+ `i` by `-n` otherwise.
96
 
97
  ``` cpp
98
  template<class InputIterator>
99
  constexpr typename iterator_traits<InputIterator>::difference_type
100
  distance(InputIterator first, InputIterator last);
101
  ```
102
 
103
+ *Preconditions:* `last` is reachable from `first`, or `InputIterator`
104
+ meets the *Cpp17RandomAccessIterator* requirements and `first` is
105
+ reachable from `last`.
106
+
107
+ *Effects:* If `InputIterator` meets the *Cpp17RandomAccessIterator*
108
+ requirements, returns `(last - first)`; otherwise, returns the number of
109
  increments needed to get from `first` to `last`.
110
 
 
 
 
 
 
111
  ``` cpp
112
  template<class InputIterator>
113
  constexpr InputIterator next(InputIterator x,
114
  typename iterator_traits<InputIterator>::difference_type n = 1);
115
  ```
 
122
  typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
123
  ```
124
 
125
  *Effects:* Equivalent to: `advance(x, -n); return x;`
126
 
127
+ ### Range iterator operations <a id="range.iter.ops">[[range.iter.ops]]</a>
128
+
129
+ The library includes the function templates `ranges::advance`,
130
+ `ranges::distance`, `ranges::next`, and `ranges::prev` to manipulate
131
+ iterators. These operations adapt to the set of operators provided by
132
+ each iterator category to provide the most efficient implementation
133
+ possible for a concrete iterator type.
134
+
135
+ [*Example 1*: `ranges::advance` uses the `+` operator to move a
136
+ `random_access_iterator` forward `n` steps in constant time. For an
137
+ iterator type that does not model `random_access_iterator`,
138
+ `ranges::advance` instead performs `n` individual increments with the
139
+ `++` operator. — *end example*]
140
+
141
+ The function templates defined in this subclause are not found by
142
+ argument-dependent name lookup [[basic.lookup.argdep]]. When found by
143
+ unqualified [[basic.lookup.unqual]] name lookup for the
144
+ *postfix-expression* in a function call [[expr.call]], they inhibit
145
+ argument-dependent name lookup.
146
+
147
+ [*Example 2*:
148
+
149
+ ``` cpp
150
+ void foo() {
151
+ using namespace std::ranges;
152
+ std::vector<int> vec{1,2,3};
153
+ distance(begin(vec), end(vec)); // #1
154
+ }
155
+ ```
156
+
157
+ The function call expression at `#1` invokes `std::ranges::distance`,
158
+ not `std::distance`, despite that (a) the iterator type returned from
159
+ `begin(vec)` and `end(vec)` may be associated with namespace `std` and
160
+ (b) `std::distance` is more specialized ([[temp.func.order]]) than
161
+ `std::ranges::distance` since the former requires its first two
162
+ parameters to have the same type.
163
+
164
+ — *end example*]
165
+
166
+ The number and order of deducible template parameters for the function
167
+ templates defined in this subclause is unspecified, except where
168
+ explicitly stated otherwise.
169
+
170
+ #### `ranges::advance` <a id="range.iter.op.advance">[[range.iter.op.advance]]</a>
171
+
172
+ ``` cpp
173
+ template<input_or_output_iterator I>
174
+ constexpr void ranges::advance(I& i, iter_difference_t<I> n);
175
+ ```
176
+
177
+ *Preconditions:* If `I` does not model `bidirectional_iterator`, `n` is
178
+ not negative.
179
+
180
+ *Effects:*
181
+
182
+ - If `I` models `random_access_iterator`, equivalent to `i += n`.
183
+ - Otherwise, if `n` is non-negative, increments `i` by `n`.
184
+ - Otherwise, decrements `i` by `-n`.
185
+
186
+ ``` cpp
187
+ template<input_or_output_iterator I, sentinel_for<I> S>
188
+ constexpr void ranges::advance(I& i, S bound);
189
+ ```
190
+
191
+ *Preconditions:* \[`i`, `bound`) denotes a range.
192
+
193
+ *Effects:*
194
+
195
+ - If `I` and `S` model `assignable_from<I&, S>`, equivalent to
196
+ `i = std::move(bound)`.
197
+ - Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent
198
+ to `ranges::advance(i, bound - i)`.
199
+ - Otherwise, while `bool(i != bound)` is `true`, increments `i`.
200
+
201
+ ``` cpp
202
+ template<input_or_output_iterator I, sentinel_for<I> S>
203
+ constexpr iter_difference_t<I> ranges::advance(I& i, iter_difference_t<I> n, S bound);
204
+ ```
205
+
206
+ *Preconditions:* If `n > 0`, \[`i`, `bound`) denotes a range. If
207
+ `n == 0`, \[`i`, `bound`) or \[`bound`, `i`) denotes a range. If
208
+ `n < 0`, \[`bound`, `i`) denotes a range, `I` models
209
+ `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
210
+
211
+ *Effects:*
212
+
213
+ - If `S` and `I` model `sized_sentinel_for<S, I>`:
214
+ - If |`n`| ≥ |`bound - i`|, equivalent to `ranges::advance(i, bound)`.
215
+ - Otherwise, equivalent to `ranges::advance(i, n)`.
216
+ - Otherwise,
217
+ - if `n` is non-negative, while `bool(i != bound)` is `true`,
218
+ increments `i` but at most `n` times.
219
+ - Otherwise, while `bool(i != bound)` is `true`, decrements `i` but at
220
+ most `-n` times.
221
+
222
+ *Returns:* `n - `M, where M is the difference between the ending and
223
+ starting positions of `i`.
224
+
225
+ #### `ranges::distance` <a id="range.iter.op.distance">[[range.iter.op.distance]]</a>
226
+
227
+ ``` cpp
228
+ template<input_or_output_iterator I, sentinel_for<I> S>
229
+ constexpr iter_difference_t<I> ranges::distance(I first, S last);
230
+ ```
231
+
232
+ *Preconditions:* \[`first`, `last`) denotes a range, or \[`last`,
233
+ `first`) denotes a range and `S` and `I` model
234
+ `same_as<S, I> && sized_sentinel_for<S, I>`.
235
+
236
+ *Effects:* If `S` and `I` model `sized_sentinel_for<S, I>`, returns
237
+ `(last - first)`; otherwise, returns the number of increments needed to
238
+ get from `first` to `last`.
239
+
240
+ ``` cpp
241
+ template<range R>
242
+ constexpr range_difference_t<R> ranges::distance(R&& r);
243
+ ```
244
+
245
+ *Effects:* If `R` models `sized_range`, equivalent to:
246
+
247
+ ``` cpp
248
+ return static_cast<range_difference_t<R>>(ranges::size(r)); // [range.prim.size]
249
+ ```
250
+
251
+ Otherwise, equivalent to:
252
+
253
+ ``` cpp
254
+ return ranges::distance(ranges::begin(r), ranges::end(r)); // [range.access]
255
+ ```
256
+
257
+ #### `ranges::next` <a id="range.iter.op.next">[[range.iter.op.next]]</a>
258
+
259
+ ``` cpp
260
+ template<input_or_output_iterator I>
261
+ constexpr I ranges::next(I x);
262
+ ```
263
+
264
+ *Effects:* Equivalent to: `++x; return x;`
265
+
266
+ ``` cpp
267
+ template<input_or_output_iterator I>
268
+ constexpr I ranges::next(I x, iter_difference_t<I> n);
269
+ ```
270
+
271
+ *Effects:* Equivalent to: `ranges::advance(x, n); return x;`
272
+
273
+ ``` cpp
274
+ template<input_or_output_iterator I, sentinel_for<I> S>
275
+ constexpr I ranges::next(I x, S bound);
276
+ ```
277
+
278
+ *Effects:* Equivalent to: `ranges::advance(x, bound); return x;`
279
+
280
+ ``` cpp
281
+ template<input_or_output_iterator I, sentinel_for<I> S>
282
+ constexpr I ranges::next(I x, iter_difference_t<I> n, S bound);
283
+ ```
284
+
285
+ *Effects:* Equivalent to: `ranges::advance(x, n, bound); return x;`
286
+
287
+ #### `ranges::prev` <a id="range.iter.op.prev">[[range.iter.op.prev]]</a>
288
+
289
+ ``` cpp
290
+ template<bidirectional_iterator I>
291
+ constexpr I ranges::prev(I x);
292
+ ```
293
+
294
+ *Effects:* Equivalent to: `-``-``x; return x;`
295
+
296
+ ``` cpp
297
+ template<bidirectional_iterator I>
298
+ constexpr I ranges::prev(I x, iter_difference_t<I> n);
299
+ ```
300
+
301
+ *Effects:* Equivalent to: `ranges::advance(x, -n); return x;`
302
+
303
+ ``` cpp
304
+ template<bidirectional_iterator I>
305
+ constexpr I ranges::prev(I x, iter_difference_t<I> n, I bound);
306
+ ```
307
+
308
+ *Effects:* Equivalent to: `ranges::advance(x, -n, bound); return x;`
309
+