From Jason Turner

[move.iterators]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpmm3z1mym/{from.md → to.md} +222 -110
tmp/tmpmm3z1mym/{from.md → to.md} RENAMED
@@ -1,6 +1,6 @@
1
- ### Move iterators <a id="move.iterators">[[move.iterators]]</a>
2
 
3
  Class template `move_iterator` is an iterator adaptor with the same
4
  behavior as the underlying iterator except that its indirection operator
5
  implicitly converts the value returned by the underlying iterator’s
6
  indirection operator to an rvalue. Some generic algorithms can be called
@@ -24,89 +24,82 @@ vector<string> v2(make_move_iterator(s.begin()),
24
  namespace std {
25
  template<class Iterator>
26
  class move_iterator {
27
  public:
28
  using iterator_type = Iterator;
29
- using iterator_category = typename iterator_traits<Iterator>::iterator_category;
30
- using value_type = typename iterator_traits<Iterator>::value_type;
31
- using difference_type = typename iterator_traits<Iterator>::difference_type;
 
32
  using pointer = Iterator;
33
- using reference = see below;
34
 
35
  constexpr move_iterator();
36
  constexpr explicit move_iterator(Iterator i);
37
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
38
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
39
 
40
- constexpr iterator_type base() const;
 
41
  constexpr reference operator*() const;
42
- constexpr pointer operator->() const;
43
 
44
  constexpr move_iterator& operator++();
45
- constexpr move_iterator operator++(int);
46
  constexpr move_iterator& operator--();
47
  constexpr move_iterator operator--(int);
48
 
49
  constexpr move_iterator operator+(difference_type n) const;
50
  constexpr move_iterator& operator+=(difference_type n);
51
  constexpr move_iterator operator-(difference_type n) const;
52
  constexpr move_iterator& operator-=(difference_type n);
53
- constexpr unspecified operator[](difference_type n) const;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  private:
56
  Iterator current; // exposition only
57
  };
58
-
59
- template <class Iterator1, class Iterator2>
60
- constexpr bool operator==(
61
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
62
- template <class Iterator1, class Iterator2>
63
- constexpr bool operator!=(
64
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
65
- template <class Iterator1, class Iterator2>
66
- constexpr bool operator<(
67
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
68
- template <class Iterator1, class Iterator2>
69
- constexpr bool operator<=(
70
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
71
- template <class Iterator1, class Iterator2>
72
- constexpr bool operator>(
73
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
74
- template <class Iterator1, class Iterator2>
75
- constexpr bool operator>=(
76
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
77
-
78
- template <class Iterator1, class Iterator2>
79
- constexpr auto operator-(
80
- const move_iterator<Iterator1>& x,
81
- const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
82
- template <class Iterator>
83
- constexpr move_iterator<Iterator> operator+(
84
- typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
85
- template <class Iterator>
86
- constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
87
  }
88
  ```
89
 
90
- Let `R` denote `iterator_traits<Iterator>::reference`. If
91
- `is_reference_v<R>` is `true`, the template specialization
92
- `move_iterator<Iterator>` shall define the nested type named `reference`
93
- as a synonym for `remove_reference_t<R>&&`, otherwise as a synonym for
94
- `R`.
95
 
96
- #### `move_iterator` requirements <a id="move.iter.requirements">[[move.iter.requirements]]</a>
 
 
 
97
 
98
- The template parameter `Iterator` shall meet the requirements of an
99
- input iterator ([[input.iterators]]). Additionally, if any of the
100
- bidirectional or random access traversal functions are instantiated, the
101
- template parameter shall meet the requirements for a Bidirectional
102
- Iterator ([[bidirectional.iterators]]) or a Random Access Iterator (
103
- [[random.access.iterators]]), respectively.
104
 
105
- #### `move_iterator` operations <a id="move.iter.ops">[[move.iter.ops]]</a>
 
 
 
 
 
 
 
 
 
 
106
 
107
- ##### `move_iterator` constructors <a id="move.iter.op.const">[[move.iter.op.const]]</a>
108
 
109
  ``` cpp
110
  constexpr move_iterator();
111
  ```
112
 
@@ -118,78 +111,84 @@ value-initialized iterator of type `Iterator`.
118
  ``` cpp
119
  constexpr explicit move_iterator(Iterator i);
120
  ```
121
 
122
  *Effects:* Constructs a `move_iterator`, initializing `current` with
123
- `i`.
124
 
125
  ``` cpp
126
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
127
  ```
128
 
 
 
129
  *Effects:* Constructs a `move_iterator`, initializing `current` with
130
  `u.base()`.
131
 
132
- *Requires:* `U` shall be convertible to `Iterator`.
133
-
134
- ##### `move_iterator::operator=` <a id="move.iter.op=">[[move.iter.op=]]</a>
135
-
136
  ``` cpp
137
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
138
  ```
139
 
 
 
140
  *Effects:* Assigns `u.base()` to `current`.
141
 
142
- *Requires:* `U` shall be convertible to `Iterator`.
143
-
144
- ##### `move_iterator` conversion <a id="move.iter.op.conv">[[move.iter.op.conv]]</a>
145
 
146
  ``` cpp
147
- constexpr Iterator base() const;
148
  ```
149
 
 
 
 
 
150
  *Returns:* `current`.
151
 
152
- ##### `move_iterator::operator*` <a id="move.iter.op.star">[[move.iter.op.star]]</a>
 
 
 
 
 
 
153
 
154
  ``` cpp
155
  constexpr reference operator*() const;
156
  ```
157
 
158
- *Returns:* `static_cast<reference>(*current)`.
159
-
160
- ##### `move_iterator::operator->` <a id="move.iter.op.ref">[[move.iter.op.ref]]</a>
161
 
162
  ``` cpp
163
- constexpr pointer operator->() const;
164
  ```
165
 
166
- *Returns:* `current`.
167
 
168
- ##### `move_iterator::operator++` <a id="move.iter.op.incr">[[move.iter.op.incr]]</a>
169
 
170
  ``` cpp
171
  constexpr move_iterator& operator++();
172
  ```
173
 
174
  *Effects:* As if by `++current`.
175
 
176
  *Returns:* `*this`.
177
 
178
  ``` cpp
179
- constexpr move_iterator operator++(int);
180
  ```
181
 
182
- *Effects:* As if by:
183
 
184
  ``` cpp
185
  move_iterator tmp = *this;
186
  ++current;
187
  return tmp;
188
  ```
189
 
190
- ##### `move_iterator::operator-{-}` <a id="move.iter.op.decr">[[move.iter.op.decr]]</a>
191
 
192
  ``` cpp
193
  constexpr move_iterator& operator--();
194
  ```
195
 
@@ -207,119 +206,232 @@ constexpr move_iterator operator--(int);
207
  move_iterator tmp = *this;
208
  --current;
209
  return tmp;
210
  ```
211
 
212
- ##### `move_iterator::operator+` <a id="move.iter.op.+">[[move.iter.op.+]]</a>
213
-
214
  ``` cpp
215
  constexpr move_iterator operator+(difference_type n) const;
216
  ```
217
 
218
  *Returns:* `move_iterator(current + n)`.
219
 
220
- ##### `move_iterator::operator+=` <a id="move.iter.op.+=">[[move.iter.op.+=]]</a>
221
-
222
  ``` cpp
223
  constexpr move_iterator& operator+=(difference_type n);
224
  ```
225
 
226
  *Effects:* As if by: `current += n;`
227
 
228
  *Returns:* `*this`.
229
 
230
- ##### `move_iterator::operator-` <a id="move.iter.op.-">[[move.iter.op.-]]</a>
231
-
232
  ``` cpp
233
  constexpr move_iterator operator-(difference_type n) const;
234
  ```
235
 
236
  *Returns:* `move_iterator(current - n)`.
237
 
238
- ##### `move_iterator::operator-=` <a id="move.iter.op.-=">[[move.iter.op.-=]]</a>
239
-
240
  ``` cpp
241
  constexpr move_iterator& operator-=(difference_type n);
242
  ```
243
 
244
  *Effects:* As if by: `current -= n;`
245
 
246
  *Returns:* `*this`.
247
 
248
- ##### `move_iterator::operator[]` <a id="move.iter.op.index">[[move.iter.op.index]]</a>
249
-
250
- ``` cpp
251
- constexpr unspecified operator[](difference_type n) const;
252
- ```
253
-
254
- *Returns:* `std::move(current[n])`.
255
-
256
- ##### `move_iterator` comparisons <a id="move.iter.op.comp">[[move.iter.op.comp]]</a>
257
 
258
  ``` cpp
259
  template<class Iterator1, class Iterator2>
260
- constexpr bool operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
 
 
 
 
261
  ```
262
 
 
 
 
263
  *Returns:* `x.base() == y.base()`.
264
 
265
- ``` cpp
266
- template <class Iterator1, class Iterator2>
267
- constexpr bool operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
268
- ```
269
-
270
- *Returns:* `!(x == y)`.
271
-
272
  ``` cpp
273
  template<class Iterator1, class Iterator2>
274
  constexpr bool operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
275
  ```
276
 
 
 
 
277
  *Returns:* `x.base() < y.base()`.
278
 
279
- ``` cpp
280
- template <class Iterator1, class Iterator2>
281
- constexpr bool operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
282
- ```
283
-
284
- *Returns:* `!(y < x)`.
285
-
286
  ``` cpp
287
  template<class Iterator1, class Iterator2>
288
  constexpr bool operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
289
  ```
290
 
 
 
 
291
  *Returns:* `y < x`.
292
 
 
 
 
 
 
 
 
 
 
 
293
  ``` cpp
294
  template<class Iterator1, class Iterator2>
295
  constexpr bool operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
296
  ```
297
 
 
 
 
298
  *Returns:* `!(x < y)`.
299
 
300
- ##### `move_iterator` non-member functions <a id="move.iter.nonmember">[[move.iter.nonmember]]</a>
 
 
 
 
 
 
 
 
 
301
 
302
  ``` cpp
303
  template<class Iterator1, class Iterator2>
304
- constexpr auto operator-(
305
- const move_iterator<Iterator1>& x,
306
- const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
 
 
 
 
 
 
307
  ```
308
 
309
  *Returns:* `x.base() - y.base()`.
310
 
311
  ``` cpp
312
  template<class Iterator>
313
- constexpr move_iterator<Iterator> operator+(
314
- typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
315
  ```
316
 
 
 
317
  *Returns:* `x + n`.
318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  ``` cpp
320
  template<class Iterator>
321
  constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
322
  ```
323
 
324
- *Returns:* `move_iterator<Iterator>(i)`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
 
1
+ ### Move iterators and sentinels <a id="move.iterators">[[move.iterators]]</a>
2
 
3
  Class template `move_iterator` is an iterator adaptor with the same
4
  behavior as the underlying iterator except that its indirection operator
5
  implicitly converts the value returned by the underlying iterator’s
6
  indirection operator to an rvalue. Some generic algorithms can be called
 
24
  namespace std {
25
  template<class Iterator>
26
  class move_iterator {
27
  public:
28
  using iterator_type = Iterator;
29
+ using iterator_concept = input_iterator_tag;
30
+ using iterator_category = see below;
31
+ using value_type = iter_value_t<Iterator>;
32
+ using difference_type = iter_difference_t<Iterator>;
33
  using pointer = Iterator;
34
+ using reference = iter_rvalue_reference_t<Iterator>;
35
 
36
  constexpr move_iterator();
37
  constexpr explicit move_iterator(Iterator i);
38
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
39
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
40
 
41
+ constexpr iterator_type base() const &;
42
+ constexpr iterator_type base() &&;
43
  constexpr reference operator*() const;
 
44
 
45
  constexpr move_iterator& operator++();
46
+ constexpr auto operator++(int);
47
  constexpr move_iterator& operator--();
48
  constexpr move_iterator operator--(int);
49
 
50
  constexpr move_iterator operator+(difference_type n) const;
51
  constexpr move_iterator& operator+=(difference_type n);
52
  constexpr move_iterator operator-(difference_type n) const;
53
  constexpr move_iterator& operator-=(difference_type n);
54
+ constexpr reference operator[](difference_type n) const;
55
+
56
+ template<sentinel_for<Iterator> S>
57
+ friend constexpr bool
58
+ operator==(const move_iterator& x, const move_sentinel<S>& y);
59
+ template<sized_sentinel_for<Iterator> S>
60
+ friend constexpr iter_difference_t<Iterator>
61
+ operator-(const move_sentinel<S>& x, const move_iterator& y);
62
+ template<sized_sentinel_for<Iterator> S>
63
+ friend constexpr iter_difference_t<Iterator>
64
+ operator-(const move_iterator& x, const move_sentinel<S>& y);
65
+ friend constexpr iter_rvalue_reference_t<Iterator>
66
+ iter_move(const move_iterator& i)
67
+ noexcept(noexcept(ranges::iter_move(i.current)));
68
+ template<indirectly_swappable<Iterator> Iterator2>
69
+ friend constexpr void
70
+ iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y)
71
+ noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
72
 
73
  private:
74
  Iterator current; // exposition only
75
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
  ```
78
 
79
+ The member *typedef-name* `iterator_category` denotes
 
 
 
 
80
 
81
+ - `random_access_iterator_tag` if the type
82
+ `iterator_traits<{}Iterator>::iterator_category` models
83
+ `derived_from<random_access_iterator_tag>`, and
84
+ - `iterator_traits<{}Iterator>::iterator_category` otherwise.
85
 
86
+ #### Requirements <a id="move.iter.requirements">[[move.iter.requirements]]</a>
 
 
 
 
 
87
 
88
+ The template parameter `Iterator` shall either meet the
89
+ *Cpp17InputIterator* requirements [[input.iterators]] or model
90
+ `input_iterator` [[iterator.concept.input]]. Additionally, if any of the
91
+ bidirectional traversal functions are instantiated, the template
92
+ parameter shall either meet the *Cpp17BidirectionalIterator*
93
+ requirements [[bidirectional.iterators]] or model
94
+ `bidirectional_iterator` [[iterator.concept.bidir]]. If any of the
95
+ random access traversal functions are instantiated, the template
96
+ parameter shall either meet the *Cpp17RandomAccessIterator* requirements
97
+ [[random.access.iterators]] or model `random_access_iterator`
98
+ [[iterator.concept.random.access]].
99
 
100
+ #### Construction and assignment <a id="move.iter.cons">[[move.iter.cons]]</a>
101
 
102
  ``` cpp
103
  constexpr move_iterator();
104
  ```
105
 
 
111
  ``` cpp
112
  constexpr explicit move_iterator(Iterator i);
113
  ```
114
 
115
  *Effects:* Constructs a `move_iterator`, initializing `current` with
116
+ `std::move(i)`.
117
 
118
  ``` cpp
119
  template<class U> constexpr move_iterator(const move_iterator<U>& u);
120
  ```
121
 
122
+ *Mandates:* `U` is convertible to `Iterator`.
123
+
124
  *Effects:* Constructs a `move_iterator`, initializing `current` with
125
  `u.base()`.
126
 
 
 
 
 
127
  ``` cpp
128
  template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
129
  ```
130
 
131
+ *Mandates:* `U` is convertible to `Iterator`.
132
+
133
  *Effects:* Assigns `u.base()` to `current`.
134
 
135
+ #### Conversion <a id="move.iter.op.conv">[[move.iter.op.conv]]</a>
 
 
136
 
137
  ``` cpp
138
+ constexpr Iterator base() const &;
139
  ```
140
 
141
+ *Constraints:* `Iterator` satisfies `copy_constructible`.
142
+
143
+ *Preconditions:* `Iterator` models `copy_constructible`.
144
+
145
  *Returns:* `current`.
146
 
147
+ ``` cpp
148
+ constexpr Iterator base() &&;
149
+ ```
150
+
151
+ *Returns:* `std::move(current)`.
152
+
153
+ #### Element access <a id="move.iter.elem">[[move.iter.elem]]</a>
154
 
155
  ``` cpp
156
  constexpr reference operator*() const;
157
  ```
158
 
159
+ *Effects:* Equivalent to: `return ranges::iter_move(current);`
 
 
160
 
161
  ``` cpp
162
+ constexpr reference operator[](difference_type n) const;
163
  ```
164
 
165
+ *Effects:* Equivalent to: `ranges::iter_move(current + n);`
166
 
167
+ #### Navigation <a id="move.iter.nav">[[move.iter.nav]]</a>
168
 
169
  ``` cpp
170
  constexpr move_iterator& operator++();
171
  ```
172
 
173
  *Effects:* As if by `++current`.
174
 
175
  *Returns:* `*this`.
176
 
177
  ``` cpp
178
+ constexpr auto operator++(int);
179
  ```
180
 
181
+ *Effects:* If `Iterator` models `forward_iterator`, equivalent to:
182
 
183
  ``` cpp
184
  move_iterator tmp = *this;
185
  ++current;
186
  return tmp;
187
  ```
188
 
189
+ Otherwise, equivalent to `++current`.
190
 
191
  ``` cpp
192
  constexpr move_iterator& operator--();
193
  ```
194
 
 
206
  move_iterator tmp = *this;
207
  --current;
208
  return tmp;
209
  ```
210
 
 
 
211
  ``` cpp
212
  constexpr move_iterator operator+(difference_type n) const;
213
  ```
214
 
215
  *Returns:* `move_iterator(current + n)`.
216
 
 
 
217
  ``` cpp
218
  constexpr move_iterator& operator+=(difference_type n);
219
  ```
220
 
221
  *Effects:* As if by: `current += n;`
222
 
223
  *Returns:* `*this`.
224
 
 
 
225
  ``` cpp
226
  constexpr move_iterator operator-(difference_type n) const;
227
  ```
228
 
229
  *Returns:* `move_iterator(current - n)`.
230
 
 
 
231
  ``` cpp
232
  constexpr move_iterator& operator-=(difference_type n);
233
  ```
234
 
235
  *Effects:* As if by: `current -= n;`
236
 
237
  *Returns:* `*this`.
238
 
239
+ #### Comparisons <a id="move.iter.op.comp">[[move.iter.op.comp]]</a>
 
 
 
 
 
 
 
 
240
 
241
  ``` cpp
242
  template<class Iterator1, class Iterator2>
243
+ constexpr bool operator==(const move_iterator<Iterator1>& x,
244
+ const move_iterator<Iterator2>& y);
245
+ template<sentinel_for<Iterator> S>
246
+ friend constexpr bool operator==(const move_iterator& x,
247
+ const move_sentinel<S>& y);
248
  ```
249
 
250
+ *Constraints:* `x.base() == y.base()` is well-formed and convertible to
251
+ `bool`.
252
+
253
  *Returns:* `x.base() == y.base()`.
254
 
 
 
 
 
 
 
 
255
  ``` cpp
256
  template<class Iterator1, class Iterator2>
257
  constexpr bool operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
258
  ```
259
 
260
+ *Constraints:* `x.base() < y.base()` is well-formed and convertible to
261
+ `bool`.
262
+
263
  *Returns:* `x.base() < y.base()`.
264
 
 
 
 
 
 
 
 
265
  ``` cpp
266
  template<class Iterator1, class Iterator2>
267
  constexpr bool operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
268
  ```
269
 
270
+ *Constraints:* `y.base() < x.base()` is well-formed and convertible to
271
+ `bool`.
272
+
273
  *Returns:* `y < x`.
274
 
275
+ ``` cpp
276
+ template<class Iterator1, class Iterator2>
277
+ constexpr bool operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
278
+ ```
279
+
280
+ *Constraints:* `y.base() < x.base()` is well-formed and convertible to
281
+ `bool`.
282
+
283
+ *Returns:* `!(y < x)`.
284
+
285
  ``` cpp
286
  template<class Iterator1, class Iterator2>
287
  constexpr bool operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
288
  ```
289
 
290
+ *Constraints:* `x.base() < y.base()` is well-formed and convertible to
291
+ `bool`.
292
+
293
  *Returns:* `!(x < y)`.
294
 
295
+ ``` cpp
296
+ template<class Iterator1, three_way_comparable_with<Iterator1> Iterator2>
297
+ constexpr compare_three_way_result_t<Iterator1, Iterator2>
298
+ operator<=>(const move_iterator<Iterator1>& x,
299
+ const move_iterator<Iterator2>& y);
300
+ ```
301
+
302
+ *Returns:* `x.base() <=> y.base()`.
303
+
304
+ #### Non-member functions <a id="move.iter.nonmember">[[move.iter.nonmember]]</a>
305
 
306
  ``` cpp
307
  template<class Iterator1, class Iterator2>
308
+ constexpr auto operator-(const move_iterator<Iterator1>& x,
309
+ const move_iterator<Iterator2>& y)
310
+ -> decltype(x.base() - y.base());
311
+ template<sized_sentinel_for<Iterator> S>
312
+ friend constexpr iter_difference_t<Iterator>
313
+ operator-(const move_sentinel<S>& x, const move_iterator& y);
314
+ template<sized_sentinel_for<Iterator> S>
315
+ friend constexpr iter_difference_t<Iterator>
316
+ operator-(const move_iterator& x, const move_sentinel<S>& y);
317
  ```
318
 
319
  *Returns:* `x.base() - y.base()`.
320
 
321
  ``` cpp
322
  template<class Iterator>
323
+ constexpr move_iterator<Iterator>
324
+ operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);
325
  ```
326
 
327
+ *Constraints:* `x + n` is well-formed and has type `Iterator`.
328
+
329
  *Returns:* `x + n`.
330
 
331
+ ``` cpp
332
+ friend constexpr iter_rvalue_reference_t<Iterator>
333
+ iter_move(const move_iterator& i)
334
+ noexcept(noexcept(ranges::iter_move(i.current)));
335
+ ```
336
+
337
+ *Effects:* Equivalent to: `return ranges::iter_move(i.current);`
338
+
339
+ ``` cpp
340
+ template<indirectly_swappable<Iterator> Iterator2>
341
+ friend constexpr void
342
+ iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y)
343
+ noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
344
+ ```
345
+
346
+ *Effects:* Equivalent to: `ranges::iter_swap(x.current, y.current)`.
347
+
348
  ``` cpp
349
  template<class Iterator>
350
  constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
351
  ```
352
 
353
+ *Returns:* `move_iterator<Iterator>(std::move(i))`.
354
+
355
+ #### Class template `move_sentinel` <a id="move.sentinel">[[move.sentinel]]</a>
356
+
357
+ Class template `move_sentinel` is a sentinel adaptor useful for denoting
358
+ ranges together with `move_iterator`. When an input iterator type `I`
359
+ and sentinel type `S` model `sentinel_for<S, I>`, `move_sentinel<S>` and
360
+ `move_iterator<I>` model
361
+ `sentinel_for<move_sentinel<S>, move_iterator<I>{>}` as well.
362
+
363
+ [*Example 1*:
364
+
365
+ A `move_if` algorithm is easily implemented with `copy_if` using
366
+ `move_iterator` and `move_sentinel`:
367
+
368
+ ``` cpp
369
+ template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,
370
+ indirect_unary_predicate<I> Pred>
371
+ requires indirectly_movable<I, O>
372
+ void move_if(I first, S last, O out, Pred pred) {
373
+ std::ranges::copy_if(move_iterator<I>{first}, move_sentinel<S>{last}, out, pred);
374
+ }
375
+ ```
376
+
377
+ — *end example*]
378
+
379
+ ``` cpp
380
+ namespace std {
381
+ template<semiregular S>
382
+ class move_sentinel {
383
+ public:
384
+ constexpr move_sentinel();
385
+ constexpr explicit move_sentinel(S s);
386
+ template<class S2>
387
+ requires convertible_to<const S2&, S>
388
+ constexpr move_sentinel(const move_sentinel<S2>& s);
389
+ template<class S2>
390
+ requires assignable_from<S&, const S2&>
391
+ constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
392
+
393
+ constexpr S base() const;
394
+ private:
395
+ S last; // exposition only
396
+ };
397
+ }
398
+ ```
399
+
400
+ #### Operations <a id="move.sent.ops">[[move.sent.ops]]</a>
401
+
402
+ ``` cpp
403
+ constexpr move_sentinel();
404
+ ```
405
+
406
+ *Effects:* Value-initializes `last`. If
407
+ `is_trivially_default_constructible_v<S>` is `true`, then this
408
+ constructor is a `constexpr` constructor.
409
+
410
+ ``` cpp
411
+ constexpr explicit move_sentinel(S s);
412
+ ```
413
+
414
+ *Effects:* Initializes `last` with `std::move(s)`.
415
+
416
+ ``` cpp
417
+ template<class S2>
418
+ requires convertible_to<const S2&, S>
419
+ constexpr move_sentinel(const move_sentinel<S2>& s);
420
+ ```
421
+
422
+ *Effects:* Initializes `last` with `s.last`.
423
+
424
+ ``` cpp
425
+ template<class S2>
426
+ requires assignable_from<S&, const S2&>
427
+ constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
428
+ ```
429
+
430
+ *Effects:* Equivalent to: `last = s.last; return *this;`
431
+
432
+ ``` cpp
433
+ constexpr S base() const;
434
+ ```
435
+
436
+ *Returns:* `last`.
437