From Jason Turner

[iterators.common]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp2nd4n5nm/{from.md → to.md} +307 -0
tmp/tmp2nd4n5nm/{from.md → to.md} RENAMED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Common iterators <a id="iterators.common">[[iterators.common]]</a>
2
+
3
+ #### Class template `common_iterator` <a id="common.iterator">[[common.iterator]]</a>
4
+
5
+ Class template `common_iterator` is an iterator/sentinel adaptor that is
6
+ capable of representing a non-common range of elements (where the types
7
+ of the iterator and sentinel differ) as a common range (where they are
8
+ the same). It does this by holding either an iterator or a sentinel, and
9
+ implementing the equality comparison operators appropriately.
10
+
11
+ [*Note 1*: The `common_iterator` type is useful for interfacing with
12
+ legacy code that expects the begin and end of a range to have the same
13
+ type. — *end note*]
14
+
15
+ [*Example 1*:
16
+
17
+ ``` cpp
18
+ template<class ForwardIterator>
19
+ void fun(ForwardIterator begin, ForwardIterator end);
20
+
21
+ list<int> s;
22
+ // populate the list s
23
+ using CI = common_iterator<counted_iterator<list<int>::iterator>, default_sentinel_t>;
24
+ // call fun on a range of 10 ints
25
+ fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel));
26
+ ```
27
+
28
+ — *end example*]
29
+
30
+ ``` cpp
31
+ namespace std {
32
+ template<input_or_output_iterator I, sentinel_for<I> S>
33
+ requires (!same_as<I, S> && copyable<I>)
34
+ class common_iterator {
35
+ public:
36
+ constexpr common_iterator() = default;
37
+ constexpr common_iterator(I i);
38
+ constexpr common_iterator(S s);
39
+ template<class I2, class S2>
40
+ requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
41
+ constexpr common_iterator(const common_iterator<I2, S2>& x);
42
+
43
+ template<class I2, class S2>
44
+ requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
45
+ assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
46
+ common_iterator& operator=(const common_iterator<I2, S2>& x);
47
+
48
+ decltype(auto) operator*();
49
+ decltype(auto) operator*() const
50
+ requires dereferenceable<const I>;
51
+ decltype(auto) operator->() const
52
+ requires see below;
53
+
54
+ common_iterator& operator++();
55
+ decltype(auto) operator++(int);
56
+
57
+ template<class I2, sentinel_for<I> S2>
58
+ requires sentinel_for<S, I2>
59
+ friend bool operator==(
60
+ const common_iterator& x, const common_iterator<I2, S2>& y);
61
+ template<class I2, sentinel_for<I> S2>
62
+ requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
63
+ friend bool operator==(
64
+ const common_iterator& x, const common_iterator<I2, S2>& y);
65
+
66
+ template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
67
+ requires sized_sentinel_for<S, I2>
68
+ friend iter_difference_t<I2> operator-(
69
+ const common_iterator& x, const common_iterator<I2, S2>& y);
70
+
71
+ friend iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
72
+ noexcept(noexcept(ranges::iter_move(declval<const I&>())))
73
+ requires input_iterator<I>;
74
+ template<indirectly_swappable<I> I2, class S2>
75
+ friend void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
76
+ noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
77
+
78
+ private:
79
+ variant<I, S> v_; // exposition only
80
+ };
81
+
82
+ template<class I, class S>
83
+ struct incrementable_traits<common_iterator<I, S>> {
84
+ using difference_type = iter_difference_t<I>;
85
+ };
86
+
87
+ template<input_iterator I, class S>
88
+ struct iterator_traits<common_iterator<I, S>> {
89
+ using iterator_concept = see below;
90
+ using iterator_category = see below;
91
+ using value_type = iter_value_t<I>;
92
+ using difference_type = iter_difference_t<I>;
93
+ using pointer = see below;
94
+ using reference = iter_reference_t<I>;
95
+ };
96
+ }
97
+ ```
98
+
99
+ #### Associated types <a id="common.iter.types">[[common.iter.types]]</a>
100
+
101
+ The nested *typedef-name*s of the specialization of `iterator_traits`
102
+ for `common_iterator<I, S>` are defined as follows.
103
+
104
+ - `iterator_concept` denotes `forward_iterator_tag` if `I` models
105
+ `forward_iterator`; otherwise it denotes `input_iterator_tag`.
106
+ - `iterator_category` denotes `forward_iterator_tag` if
107
+ `iterator_traits<I>::iterator_category` models
108
+ `derived_from<forward_iterator_tag>`; otherwise it denotes
109
+ `input_iterator_tag`.
110
+ - If the expression `a.operator->()` is well-formed, where `a` is an
111
+ lvalue of type `const common_iterator<I, S>`, then `pointer` denotes
112
+ the type of that expression. Otherwise, `pointer` denotes `void`.
113
+
114
+ #### Constructors and conversions <a id="common.iter.const">[[common.iter.const]]</a>
115
+
116
+ ``` cpp
117
+ constexpr common_iterator(I i);
118
+ ```
119
+
120
+ *Effects:* Initializes `v_` as if by
121
+ `v_{in_place_type<I>, std::move(i)}`.
122
+
123
+ ``` cpp
124
+ constexpr common_iterator(S s);
125
+ ```
126
+
127
+ *Effects:* Initializes `v_` as if by
128
+ `v_{in_place_type<S>, std::move(s)}`.
129
+
130
+ ``` cpp
131
+ template<class I2, class S2>
132
+ requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
133
+ constexpr common_iterator(const common_iterator<I2, S2>& x);
134
+ ```
135
+
136
+ *Preconditions:* `x.v_.valueless_by_exception()` is `false`.
137
+
138
+ *Effects:* Initializes `v_` as if by
139
+ `v_{in_place_index<`i`>, get<`i`>(x.v_)}`, where i is `x.v_.index()`.
140
+
141
+ ``` cpp
142
+ template<class I2, class S2>
143
+ requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
144
+ assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
145
+ common_iterator& operator=(const common_iterator<I2, S2>& x);
146
+ ```
147
+
148
+ *Preconditions:* `x.v_.valueless_by_exception()` is `false`.
149
+
150
+ *Effects:* Equivalent to:
151
+
152
+ - If `v_.index() == x.v_.index()`, then `get<`i`>(v_) = get<`i`>(x.v_)`.
153
+ - Otherwise, `v_.emplace<`i`>(get<`i`>(x.v_))`.
154
+
155
+ where i is `x.v_.index()`.
156
+
157
+ *Returns:* `*this`
158
+
159
+ #### Accessors <a id="common.iter.access">[[common.iter.access]]</a>
160
+
161
+ ``` cpp
162
+ decltype(auto) operator*();
163
+ decltype(auto) operator*() const
164
+ requires dereferenceable<const I>;
165
+ ```
166
+
167
+ *Preconditions:* `holds_alternative<I>(v_)`.
168
+
169
+ *Effects:* Equivalent to: `return *get<I>(v_);`
170
+
171
+ ``` cpp
172
+ decltype(auto) operator->() const
173
+ requires see below;
174
+ ```
175
+
176
+ The expression in the requires clause is equivalent to:
177
+
178
+ ``` cpp
179
+ indirectly_readable<const I> &&
180
+ (requires(const I& i) { i.operator->(); } ||
181
+ is_reference_v<iter_reference_t<I>> ||
182
+ constructible_from<iter_value_t<I>, iter_reference_t<I>>)
183
+ ```
184
+
185
+ *Preconditions:* `holds_alternative<I>(v_)`.
186
+
187
+ *Effects:*
188
+
189
+ - If `I` is a pointer type or if the expression
190
+ `get<I>(v_).operator->()` is well-formed, equivalent to:
191
+ `return get<I>(v_);`
192
+ - Otherwise, if `iter_reference_t<I>` is a reference type, equivalent
193
+ to:
194
+ ``` cpp
195
+ auto&& tmp = *get<I>(v_);
196
+ return addressof(tmp);
197
+ ```
198
+ - Otherwise, equivalent to: `return `*`proxy`*`(*get<I>(v_));` where
199
+ *proxy* is the exposition-only class:
200
+ ``` cpp
201
+ class proxy {
202
+ iter_value_t<I> keep_;
203
+ proxy(iter_reference_t<I>&& x)
204
+ : keep_(std::move(x)) {}
205
+ public:
206
+ const iter_value_t<I>* operator->() const {
207
+ return addressof(keep_);
208
+ }
209
+ };
210
+ ```
211
+
212
+ #### Navigation <a id="common.iter.nav">[[common.iter.nav]]</a>
213
+
214
+ ``` cpp
215
+ common_iterator& operator++();
216
+ ```
217
+
218
+ *Preconditions:* `holds_alternative<I>(v_)`.
219
+
220
+ *Effects:* Equivalent to `++get<I>(v_)`.
221
+
222
+ *Returns:* `*this`.
223
+
224
+ ``` cpp
225
+ decltype(auto) operator++(int);
226
+ ```
227
+
228
+ *Preconditions:* `holds_alternative<I>(v_)`.
229
+
230
+ *Effects:* If `I` models `forward_iterator`, equivalent to:
231
+
232
+ ``` cpp
233
+ common_iterator tmp = *this;
234
+ ++*this;
235
+ return tmp;
236
+ ```
237
+
238
+ Otherwise, equivalent to: `return get<I>(v_)++;`
239
+
240
+ #### Comparisons <a id="common.iter.cmp">[[common.iter.cmp]]</a>
241
+
242
+ ``` cpp
243
+ template<class I2, sentinel_for<I> S2>
244
+ requires sentinel_for<S, I2>
245
+ friend bool operator==(
246
+ const common_iterator& x, const common_iterator<I2, S2>& y);
247
+ ```
248
+
249
+ *Preconditions:* `x.v_.valueless_by_exception()` and
250
+ `y.v_.valueless_by_exception()` are each `false`.
251
+
252
+ *Returns:* `true` if i` == `j, and otherwise
253
+ `get<`i`>(x.v_) == get<`j`>(y.v_)`, where i is `x.v_.index()` and j is
254
+ `y.v_.index()`.
255
+
256
+ ``` cpp
257
+ template<class I2, sentinel_for<I> S2>
258
+ requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
259
+ friend bool operator==(
260
+ const common_iterator& x, const common_iterator<I2, S2>& y);
261
+ ```
262
+
263
+ *Preconditions:* `x.v_.valueless_by_exception()` and
264
+ `y.v_.valueless_by_exception()` are each `false`.
265
+
266
+ *Returns:* `true` if i and j are each `1`, and otherwise
267
+ `get<`i`>(x.v_) == get<`j`>(y.v_)`, where i is `x.v_.index()` and j is
268
+ `y.v_.index()`.
269
+
270
+ ``` cpp
271
+ template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
272
+ requires sized_sentinel_for<S, I2>
273
+ friend iter_difference_t<I2> operator-(
274
+ const common_iterator& x, const common_iterator<I2, S2>& y);
275
+ ```
276
+
277
+ *Preconditions:* `x.v_.valueless_by_exception()` and
278
+ `y.v_.valueless_by_exception()` are each `false`.
279
+
280
+ *Returns:* `0` if i and j are each `1`, and otherwise
281
+ `get<`i`>(x.v_) - get<`j`>(y.v_)`, where i is `x.v_.index()` and j is
282
+ `y.v_.index()`.
283
+
284
+ #### Customization <a id="common.iter.cust">[[common.iter.cust]]</a>
285
+
286
+ ``` cpp
287
+ friend iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
288
+ noexcept(noexcept(ranges::iter_move(declval<const I&>())))
289
+ requires input_iterator<I>;
290
+ ```
291
+
292
+ *Preconditions:* `holds_alternative<I>(v_)`.
293
+
294
+ *Effects:* Equivalent to: `return ranges::iter_move(get<I>(i.v_));`
295
+
296
+ ``` cpp
297
+ template<indirectly_swappable<I> I2, class S2>
298
+ friend void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
299
+ noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
300
+ ```
301
+
302
+ *Preconditions:* `holds_alternative<I>(x.v_)` and
303
+ `holds_alternative<I2>(y.v_)` are each `true`.
304
+
305
+ *Effects:* Equivalent to
306
+ `ranges::iter_swap(get<I>(x.v_), get<I2>(y.v_))`.
307
+