From Jason Turner

[iterators.common]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpf_95pdlt/{from.md → to.md} +74 -40
tmp/tmpf_95pdlt/{from.md → to.md} RENAMED
@@ -31,50 +31,50 @@ fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel));
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
  };
@@ -101,17 +101,17 @@ namespace std {
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);
@@ -140,11 +140,11 @@ template<class I2, class S2>
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:
@@ -157,34 +157,34 @@ where i is `x.v_.index()`.
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:
@@ -198,53 +198,87 @@ indirectly_readable<const I> &&
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`.
@@ -254,11 +288,11 @@ friend bool operator==(
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`.
@@ -268,36 +302,36 @@ friend bool operator==(
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`.
 
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() requires default_initializable<I> = 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
+ constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
47
 
48
+ constexpr decltype(auto) operator*();
49
+ constexpr decltype(auto) operator*() const
50
  requires dereferenceable<const I>;
51
+ constexpr auto operator->() const
52
  requires see below;
53
 
54
+ constexpr common_iterator& operator++();
55
+ constexpr decltype(auto) operator++(int);
56
 
57
  template<class I2, sentinel_for<I> S2>
58
  requires sentinel_for<S, I2>
59
+ friend constexpr 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 constexpr 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 constexpr iter_difference_t<I2> operator-(
69
  const common_iterator& x, const common_iterator<I2, S2>& y);
70
 
71
+ friend constexpr 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 constexpr 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
  };
 
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 the
107
+ *qualified-id* `iterator_traits<I>::iterator_category` is valid and
108
+ denotes a type that models `derived_from<forward_iterator_tag>`;
109
+ otherwise it denotes `input_iterator_tag`.
110
+ - Let `a` denote an lvalue of type `const common_iterator<I, S>`. If the
111
+ expression `a.operator->()` is well-formed, then `pointer` denotes
112
+ `decltype(a.operator->())`. 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);
 
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
+ constexpr 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:
 
157
  *Returns:* `*this`
158
 
159
  #### Accessors <a id="common.iter.access">[[common.iter.access]]</a>
160
 
161
  ``` cpp
162
+ constexpr decltype(auto) operator*();
163
+ constexpr decltype(auto) operator*() const
164
  requires dereferenceable<const I>;
165
  ```
166
 
167
+ *Preconditions:* `holds_alternative<I>(v_)` is `true`.
168
 
169
  *Effects:* Equivalent to: `return *get<I>(v_);`
170
 
171
  ``` cpp
172
+ constexpr 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_)` is `true`.
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:
 
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
+ constexpr proxy(iter_reference_t<I>&& x)
204
  : keep_(std::move(x)) {}
205
  public:
206
+ constexpr const iter_value_t<I>* operator->() const noexcept {
207
  return addressof(keep_);
208
  }
209
  };
210
  ```
211
 
212
  #### Navigation <a id="common.iter.nav">[[common.iter.nav]]</a>
213
 
214
  ``` cpp
215
+ constexpr common_iterator& operator++();
216
  ```
217
 
218
+ *Preconditions:* `holds_alternative<I>(v_)` is `true`.
219
 
220
  *Effects:* Equivalent to `++get<I>(v_)`.
221
 
222
  *Returns:* `*this`.
223
 
224
  ``` cpp
225
+ constexpr decltype(auto) operator++(int);
226
  ```
227
 
228
+ *Preconditions:* `holds_alternative<I>(v_)` is `true`.
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, if `requires(I& i) { { *i++ } -> `*`can-reference`*`; }` is
239
+ `true` or
240
+
241
+ ``` cpp
242
+ indirectly_readable<I> && constructible_from<iter_value_t<I>, iter_reference_t<I>> &&
243
+ move_constructible<iter_value_t<I>>
244
+ ```
245
+
246
+ is `false`, equivalent to:
247
+
248
+ ``` cpp
249
+ return get<I>(v_)++;
250
+ ```
251
+
252
+ Otherwise, equivalent to:
253
+
254
+ ``` cpp
255
+ postfix-proxy p(**this);
256
+ ++*this;
257
+ return p;
258
+ ```
259
+
260
+ where *postfix-proxy* is the exposition-only class:
261
+
262
+ ``` cpp
263
+ class postfix-proxy {
264
+ iter_value_t<I> keep_;
265
+ constexpr postfix-proxy(iter_reference_t<I>&& x)
266
+ : keep_(std::forward<iter_reference_t<I>>(x)) {}
267
+ public:
268
+ constexpr const iter_value_t<I>& operator*() const noexcept {
269
+ return keep_;
270
+ }
271
+ };
272
+ ```
273
 
274
  #### Comparisons <a id="common.iter.cmp">[[common.iter.cmp]]</a>
275
 
276
  ``` cpp
277
  template<class I2, sentinel_for<I> S2>
278
  requires sentinel_for<S, I2>
279
+ friend constexpr bool operator==(
280
  const common_iterator& x, const common_iterator<I2, S2>& y);
281
  ```
282
 
283
  *Preconditions:* `x.v_.valueless_by_exception()` and
284
  `y.v_.valueless_by_exception()` are each `false`.
 
288
  `y.v_.index()`.
289
 
290
  ``` cpp
291
  template<class I2, sentinel_for<I> S2>
292
  requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
293
+ friend constexpr bool operator==(
294
  const common_iterator& x, const common_iterator<I2, S2>& y);
295
  ```
296
 
297
  *Preconditions:* `x.v_.valueless_by_exception()` and
298
  `y.v_.valueless_by_exception()` are each `false`.
 
302
  `y.v_.index()`.
303
 
304
  ``` cpp
305
  template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
306
  requires sized_sentinel_for<S, I2>
307
+ friend constexpr iter_difference_t<I2> operator-(
308
  const common_iterator& x, const common_iterator<I2, S2>& y);
309
  ```
310
 
311
  *Preconditions:* `x.v_.valueless_by_exception()` and
312
  `y.v_.valueless_by_exception()` are each `false`.
313
 
314
  *Returns:* `0` if i and j are each `1`, and otherwise
315
  `get<`i`>(x.v_) - get<`j`>(y.v_)`, where i is `x.v_.index()` and j is
316
  `y.v_.index()`.
317
 
318
+ #### Customizations <a id="common.iter.cust">[[common.iter.cust]]</a>
319
 
320
  ``` cpp
321
+ friend constexpr iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
322
  noexcept(noexcept(ranges::iter_move(declval<const I&>())))
323
  requires input_iterator<I>;
324
  ```
325
 
326
+ *Preconditions:* `holds_alternative<I>(i.v_)` is `true`.
327
 
328
  *Effects:* Equivalent to: `return ranges::iter_move(get<I>(i.v_));`
329
 
330
  ``` cpp
331
  template<indirectly_swappable<I> I2, class S2>
332
+ friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
333
  noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
334
  ```
335
 
336
  *Preconditions:* `holds_alternative<I>(x.v_)` and
337
  `holds_alternative<I2>(y.v_)` are each `true`.