From Jason Turner

[iterator.assoc.types]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp0_w3x_7b/{from.md → to.md} +323 -0
tmp/tmp0_w3x_7b/{from.md → to.md} RENAMED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Associated types <a id="iterator.assoc.types">[[iterator.assoc.types]]</a>
2
+
3
+ #### Incrementable traits <a id="incrementable.traits">[[incrementable.traits]]</a>
4
+
5
+ To implement algorithms only in terms of incrementable types, it is
6
+ often necessary to determine the difference type that corresponds to a
7
+ particular incrementable type. Accordingly, it is required that if `WI`
8
+ is the name of a type that models the `weakly_incrementable` concept
9
+ [[iterator.concept.winc]], the type
10
+
11
+ ``` cpp
12
+ iter_difference_t<WI>
13
+ ```
14
+
15
+ be defined as the incrementable type’s difference type.
16
+
17
+ ``` cpp
18
+ namespace std {
19
+ template<class> struct incrementable_traits { };
20
+
21
+ template<class T>
22
+ requires is_object_v<T>
23
+ struct incrementable_traits<T*> {
24
+ using difference_type = ptrdiff_t;
25
+ };
26
+
27
+ template<class I>
28
+ struct incrementable_traits<const I>
29
+ : incrementable_traits<I> { };
30
+
31
+ template<class T>
32
+ requires requires { typename T::difference_type; }
33
+ struct incrementable_traits<T> {
34
+ using difference_type = typename T::difference_type;
35
+ };
36
+
37
+ template<class T>
38
+ requires (!requires { typename T::difference_type; } &&
39
+ requires(const T& a, const T& b) { { a - b } -> integral; })
40
+ struct incrementable_traits<T> {
41
+ using difference_type = make_signed_t<decltype(declval<T>() - declval<T>())>;
42
+ };
43
+
44
+ template<class T>
45
+ using iter_difference_t = see below;
46
+ }
47
+ ```
48
+
49
+ Let R_`I` be `remove_cvref_t<I>`. The type `iter_difference_t<I>`
50
+ denotes
51
+
52
+ - `incrementable_traits<R_I>::difference_type` if `iterator_traits<R_I>`
53
+ names a specialization generated from the primary template, and
54
+ - `iterator_traits<R_I>::difference_type` otherwise.
55
+
56
+ Users may specialize `incrementable_traits` on program-defined types.
57
+
58
+ #### Indirectly readable traits <a id="readable.traits">[[readable.traits]]</a>
59
+
60
+ To implement algorithms only in terms of indirectly readable types, it
61
+ is often necessary to determine the value type that corresponds to a
62
+ particular indirectly readable type. Accordingly, it is required that if
63
+ `R` is the name of a type that models the `indirectly_readable` concept
64
+ [[iterator.concept.readable]], the type
65
+
66
+ ``` cpp
67
+ iter_value_t<R>
68
+ ```
69
+
70
+ be defined as the indirectly readable type’s value type.
71
+
72
+ ``` cpp
73
+ template<class> struct cond-value-type { }; // exposition only
74
+ template<class T>
75
+ requires is_object_v<T>
76
+ struct cond-value-type<T> {
77
+ using value_type = remove_cv_t<T>;
78
+ };
79
+
80
+ template<class> struct indirectly_readable_traits { };
81
+
82
+ template<class T>
83
+ struct indirectly_readable_traits<T*>
84
+ : cond-value-type<T> { };
85
+
86
+ template<class I>
87
+ requires is_array_v<I>
88
+ struct indirectly_readable_traits<I> {
89
+ using value_type = remove_cv_t<remove_extent_t<I>>;
90
+ };
91
+
92
+ template<class I>
93
+ struct indirectly_readable_traits<const I>
94
+ : indirectly_readable_traits<I> { };
95
+
96
+ template<class T>
97
+ requires requires { typename T::value_type; }
98
+ struct indirectly_readable_traits<T>
99
+ : cond-value-type<typename T::value_type> { };
100
+
101
+ template<class T>
102
+ requires requires { typename T::element_type; }
103
+ struct indirectly_readable_traits<T>
104
+ : cond-value-type<typename T::element_type> { };
105
+
106
+ template<class T> using iter_value_t = see below;
107
+ ```
108
+
109
+ Let R_`I` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
110
+
111
+ - `indirectly_readable_traits<R_I>::value_type` if
112
+ `iterator_traits<R_I>` names a specialization generated from the
113
+ primary template, and
114
+ - `iterator_traits<R_I>::value_type` otherwise.
115
+
116
+ Class template `indirectly_readable_traits` may be specialized on
117
+ program-defined types.
118
+
119
+ [*Note 1*: Some legacy output iterators define a nested type named
120
+ `value_type` that is an alias for `void`. These types are not
121
+ `indirectly_readable` and have no associated value types. — *end note*]
122
+
123
+ [*Note 2*: Smart pointers like `shared_ptr<int>` are
124
+ `indirectly_readable` and have an associated value type, but a smart
125
+ pointer like `shared_ptr<void>` is not `indirectly_readable` and has no
126
+ associated value type. — *end note*]
127
+
128
+ #### Iterator traits <a id="iterator.traits">[[iterator.traits]]</a>
129
+
130
+ To implement algorithms only in terms of iterators, it is sometimes
131
+ necessary to determine the iterator category that corresponds to a
132
+ particular iterator type. Accordingly, it is required that if `I` is the
133
+ type of an iterator, the type
134
+
135
+ ``` cpp
136
+ iterator_traits<I>::iterator_category
137
+ ```
138
+
139
+ be defined as the iterator’s iterator category. In addition, the types
140
+
141
+ ``` cpp
142
+ iterator_traits<I>::pointer
143
+ iterator_traits<I>::reference
144
+ ```
145
+
146
+ shall be defined as the iterator’s pointer and reference types; that is,
147
+ for an iterator object `a` of class type, the same type as
148
+ `decltype(a.operator->())` and `decltype(*a)`, respectively. The type
149
+ `iterator_traits<I>::pointer` shall be `void` for an iterator of class
150
+ type `I` that does not support `operator->`. Additionally, in the case
151
+ of an output iterator, the types
152
+
153
+ ``` cpp
154
+ iterator_traits<I>::value_type
155
+ iterator_traits<I>::difference_type
156
+ iterator_traits<I>::reference
157
+ ```
158
+
159
+ may be defined as `void`.
160
+
161
+ The definitions in this subclause make use of the following
162
+ exposition-only concepts:
163
+
164
+ ``` cpp
165
+ template<class I>
166
+ concept cpp17-iterator =
167
+ copyable<I> && requires(I i) {
168
+ { *i } -> can-reference;
169
+ { ++i } -> same_as<I&>;
170
+ { *i++ } -> can-reference;
171
+ };
172
+
173
+ template<class I>
174
+ concept cpp17-input-iterator =
175
+ cpp17-iterator<I> && equality_comparable<I> && requires(I i) {
176
+ typename incrementable_traits<I>::difference_type;
177
+ typename indirectly_readable_traits<I>::value_type;
178
+ typename common_reference_t<iter_reference_t<I>&&,
179
+ typename indirectly_readable_traits<I>::value_type&>;
180
+ typename common_reference_t<decltype(*i++)&&,
181
+ typename indirectly_readable_traits<I>::value_type&>;
182
+ requires signed_integral<typename incrementable_traits<I>::difference_type>;
183
+ };
184
+
185
+ template<class I>
186
+ concept cpp17-forward-iterator =
187
+ cpp17-input-iterator<I> && constructible_from<I> &&
188
+ is_lvalue_reference_v<iter_reference_t<I>> &&
189
+ same_as<remove_cvref_t<iter_reference_t<I>>,
190
+ typename indirectly_readable_traits<I>::value_type> &&
191
+ requires(I i) {
192
+ { i++ } -> convertible_to<const I&>;
193
+ { *i++ } -> same_as<iter_reference_t<I>>;
194
+ };
195
+
196
+ template<class I>
197
+ concept cpp17-bidirectional-iterator =
198
+ cpp17-forward-iterator<I> && requires(I i) {
199
+ { --i } -> same_as<I&>;
200
+ { i-- } -> convertible_to<const I&>;
201
+ { *i-- } -> same_as<iter_reference_t<I>>;
202
+ };
203
+
204
+ template<class I>
205
+ concept cpp17-random-access-iterator =
206
+ cpp17-bidirectional-iterator<I> && totally_ordered<I> &&
207
+ requires(I i, typename incrementable_traits<I>::difference_type n) {
208
+ { i += n } -> same_as<I&>;
209
+ { i -= n } -> same_as<I&>;
210
+ { i + n } -> same_as<I>;
211
+ { n + i } -> same_as<I>;
212
+ { i - n } -> same_as<I>;
213
+ { i - i } -> same_as<decltype(n)>;
214
+ { i[n] } -> convertible_to<iter_reference_t<I>>;
215
+ };
216
+ ```
217
+
218
+ The members of a specialization `iterator_traits<I>` generated from the
219
+ `iterator_traits` primary template are computed as follows:
220
+
221
+ - If `I` has valid [[temp.deduct]] member types `difference_type`,
222
+ `value_type`, `reference`, and `iterator_category`, then
223
+ `iterator_traits<I>` has the following publicly accessible members:
224
+ ``` cpp
225
+ using iterator_category = typename I::iterator_category;
226
+ using value_type = typename I::value_type;
227
+ using difference_type = typename I::difference_type;
228
+ using pointer = see below;
229
+ using reference = typename I::reference;
230
+ ```
231
+
232
+ If the *qualified-id* `I::pointer` is valid and denotes a type, then
233
+ `iterator_traits<I>::pointer` names that type; otherwise, it names
234
+ `void`.
235
+ - Otherwise, if `I` satisfies the exposition-only concept
236
+ `cpp17-input-iterator`, `iterator_traits<I>` has the following
237
+ publicly accessible members:
238
+ ``` cpp
239
+ using iterator_category = see below;
240
+ using value_type = typename indirectly_readable_traits<I>::value_type;
241
+ using difference_type = typename incrementable_traits<I>::difference_type;
242
+ using pointer = see below;
243
+ using reference = see below;
244
+ ```
245
+
246
+ - If the *qualified-id* `I::pointer` is valid and denotes a type,
247
+ `pointer` names that type. Otherwise, if
248
+ `decltype({}declval<I&>().operator->())` is well-formed, then
249
+ `pointer` names that type. Otherwise, `pointer` names `void`.
250
+ - If the *qualified-id* `I::reference` is valid and denotes a type,
251
+ `reference` names that type. Otherwise, `reference` names
252
+ `iter_reference_t<I>`.
253
+ - If the *qualified-id* `I::iterator_category` is valid and denotes a
254
+ type, `iterator_category` names that type. Otherwise,
255
+ `iterator_category` names:
256
+ - `random_access_iterator_tag` if `I` satisfies
257
+ `cpp17-random-access-iterator`, or otherwise
258
+ - `bidirectional_iterator_tag` if `I` satisfies
259
+ `cpp17-bidirectional-iterator`, or otherwise
260
+ - `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`,
261
+ or otherwise
262
+ - `input_iterator_tag`.
263
+ - Otherwise, if `I` satisfies the exposition-only concept
264
+ `cpp17-iterator`, then `iterator_traits<I>` has the following publicly
265
+ accessible members:
266
+ ``` cpp
267
+ using iterator_category = output_iterator_tag;
268
+ using value_type = void;
269
+ using difference_type = see below;
270
+ using pointer = void;
271
+ using reference = void;
272
+ ```
273
+
274
+ If the *qualified-id* `incrementable_traits<I>::difference_type` is
275
+ valid and denotes a type, then `difference_type` names that type;
276
+ otherwise, it names `void`.
277
+ - Otherwise, `iterator_traits<I>` has no members by any of the above
278
+ names.
279
+
280
+ Explicit or partial specializations of `iterator_traits` may have a
281
+ member type `iterator_concept` that is used to indicate conformance to
282
+ the iterator concepts [[iterator.concepts]].
283
+
284
+ `iterator_traits` is specialized for pointers as
285
+
286
+ ``` cpp
287
+ namespace std {
288
+ template<class T>
289
+ requires is_object_v<T>
290
+ struct iterator_traits<T*> {
291
+ using iterator_concept = contiguous_iterator_tag;
292
+ using iterator_category = random_access_iterator_tag;
293
+ using value_type = remove_cv_t<T>;
294
+ using difference_type = ptrdiff_t;
295
+ using pointer = T*;
296
+ using reference = T&;
297
+ };
298
+ }
299
+ ```
300
+
301
+ [*Example 1*:
302
+
303
+ To implement a generic `reverse` function, a C++ program can do the
304
+ following:
305
+
306
+ ``` cpp
307
+ template<class BI>
308
+ void reverse(BI first, BI last) {
309
+ typename iterator_traits<BI>::difference_type n =
310
+ distance(first, last);
311
+ --n;
312
+ while(n > 0) {
313
+ typename iterator_traits<BI>::value_type
314
+ tmp = *first;
315
+ *first++ = *--last;
316
+ *last = tmp;
317
+ n -= 2;
318
+ }
319
+ }
320
+ ```
321
+
322
+ — *end example*]
323
+