Line data Source code
1 : // -*- C++ -*-
2 : //===----------------------------------------------------------------------===//
3 : //
4 : // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 : // See https://llvm.org/LICENSE.txt for license information.
6 : // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H
11 : #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H
12 :
13 : #include <__compare/compare_three_way_result.h>
14 : #include <__compare/three_way_comparable.h>
15 : #include <__concepts/assignable.h>
16 : #include <__concepts/convertible_to.h>
17 : #include <__concepts/derived_from.h>
18 : #include <__concepts/same_as.h>
19 : #include <__config>
20 : #include <__iterator/concepts.h>
21 : #include <__iterator/incrementable_traits.h>
22 : #include <__iterator/iter_move.h>
23 : #include <__iterator/iter_swap.h>
24 : #include <__iterator/iterator_traits.h>
25 : #include <__iterator/move_sentinel.h>
26 : #include <__iterator/readable_traits.h>
27 : #include <__type_traits/conditional.h>
28 : #include <__type_traits/enable_if.h>
29 : #include <__type_traits/is_assignable.h>
30 : #include <__type_traits/is_constructible.h>
31 : #include <__type_traits/is_convertible.h>
32 : #include <__type_traits/is_reference.h>
33 : #include <__type_traits/is_same.h>
34 : #include <__type_traits/remove_reference.h>
35 : #include <__utility/declval.h>
36 : #include <__utility/move.h>
37 :
38 : #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
39 : # pragma GCC system_header
40 : #endif
41 :
42 : _LIBCPP_BEGIN_NAMESPACE_STD
43 :
44 : #if _LIBCPP_STD_VER > 17
45 : template<class _Iter, class = void>
46 : struct __move_iter_category_base {};
47 :
48 : template<class _Iter>
49 : requires requires { typename iterator_traits<_Iter>::iterator_category; }
50 : struct __move_iter_category_base<_Iter> {
51 : using iterator_category = _If<
52 : derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>,
53 : random_access_iterator_tag,
54 : typename iterator_traits<_Iter>::iterator_category
55 : >;
56 : };
57 :
58 : template<class _Iter, class _Sent>
59 : concept __move_iter_comparable = requires {
60 : { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>;
61 : };
62 : #endif // _LIBCPP_STD_VER > 17
63 :
64 : template <class _Iter>
65 : class _LIBCPP_TEMPLATE_VIS move_iterator
66 : #if _LIBCPP_STD_VER > 17
67 : : public __move_iter_category_base<_Iter>
68 : #endif
69 : {
70 : public:
71 : #if _LIBCPP_STD_VER > 17
72 : using iterator_type = _Iter;
73 : using iterator_concept = input_iterator_tag;
74 : // iterator_category is inherited and not always present
75 : using value_type = iter_value_t<_Iter>;
76 : using difference_type = iter_difference_t<_Iter>;
77 : using pointer = _Iter;
78 : using reference = iter_rvalue_reference_t<_Iter>;
79 : #else
80 : typedef _Iter iterator_type;
81 : typedef _If<
82 : __is_cpp17_random_access_iterator<_Iter>::value,
83 : random_access_iterator_tag,
84 : typename iterator_traits<_Iter>::iterator_category
85 : > iterator_category;
86 : typedef typename iterator_traits<iterator_type>::value_type value_type;
87 : typedef typename iterator_traits<iterator_type>::difference_type difference_type;
88 : typedef iterator_type pointer;
89 :
90 : typedef typename iterator_traits<iterator_type>::reference __reference;
91 : typedef typename conditional<
92 : is_reference<__reference>::value,
93 : __libcpp_remove_reference_t<__reference>&&,
94 : __reference
95 : >::type reference;
96 : #endif // _LIBCPP_STD_VER > 17
97 :
98 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
99 0 : explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {}
100 :
101 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
102 0 : move_iterator& operator++() { ++__current_; return *this; }
103 :
104 : _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
105 : pointer operator->() const { return __current_; }
106 :
107 : #if _LIBCPP_STD_VER > 17
108 : _LIBCPP_HIDE_FROM_ABI constexpr
109 : move_iterator() requires is_constructible_v<_Iter> : __current_() {}
110 :
111 : template <class _Up>
112 : requires (!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter>
113 : _LIBCPP_HIDE_FROM_ABI constexpr
114 : move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
115 :
116 : template <class _Up>
117 : requires (!_IsSame<_Up, _Iter>::value) &&
118 : convertible_to<const _Up&, _Iter> &&
119 : assignable_from<_Iter&, const _Up&>
120 : _LIBCPP_HIDE_FROM_ABI constexpr
121 : move_iterator& operator=(const move_iterator<_Up>& __u) {
122 : __current_ = __u.base();
123 : return *this;
124 : }
125 :
126 : _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; }
127 : _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); }
128 :
129 : _LIBCPP_HIDE_FROM_ABI constexpr
130 : reference operator*() const { return ranges::iter_move(__current_); }
131 : _LIBCPP_HIDE_FROM_ABI constexpr
132 : reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); }
133 :
134 : _LIBCPP_HIDE_FROM_ABI constexpr
135 : auto operator++(int)
136 : requires forward_iterator<_Iter>
137 : {
138 : move_iterator __tmp(*this); ++__current_; return __tmp;
139 : }
140 :
141 : _LIBCPP_HIDE_FROM_ABI constexpr
142 : void operator++(int) { ++__current_; }
143 : #else
144 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
145 : move_iterator() : __current_() {}
146 :
147 : template <class _Up, class = __enable_if_t<
148 : !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value
149 : > >
150 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
151 : move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
152 :
153 : template <class _Up, class = __enable_if_t<
154 : !is_same<_Up, _Iter>::value &&
155 : is_convertible<const _Up&, _Iter>::value &&
156 : is_assignable<_Iter&, const _Up&>::value
157 : > >
158 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
159 : move_iterator& operator=(const move_iterator<_Up>& __u) {
160 : __current_ = __u.base();
161 : return *this;
162 : }
163 :
164 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
165 0 : _Iter base() const { return __current_; }
166 :
167 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
168 0 : reference operator*() const { return static_cast<reference>(*__current_); }
169 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
170 : reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); }
171 :
172 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
173 : move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; }
174 : #endif // _LIBCPP_STD_VER > 17
175 :
176 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
177 : move_iterator& operator--() { --__current_; return *this; }
178 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
179 : move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; }
180 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
181 : move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); }
182 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
183 : move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; }
184 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
185 : move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); }
186 : _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
187 : move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; }
188 :
189 : #if _LIBCPP_STD_VER > 17
190 : template<sentinel_for<_Iter> _Sent>
191 : friend _LIBCPP_HIDE_FROM_ABI constexpr
192 : bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
193 : requires __move_iter_comparable<_Iter, _Sent>
194 : {
195 : return __x.base() == __y.base();
196 : }
197 :
198 : template<sized_sentinel_for<_Iter> _Sent>
199 : friend _LIBCPP_HIDE_FROM_ABI constexpr
200 : iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y)
201 : {
202 : return __x.base() - __y.base();
203 : }
204 :
205 : template<sized_sentinel_for<_Iter> _Sent>
206 : friend _LIBCPP_HIDE_FROM_ABI constexpr
207 : iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y)
208 : {
209 : return __x.base() - __y.base();
210 : }
211 :
212 : friend _LIBCPP_HIDE_FROM_ABI constexpr
213 : iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i)
214 : noexcept(noexcept(ranges::iter_move(__i.__current_)))
215 : {
216 : return ranges::iter_move(__i.__current_);
217 : }
218 :
219 : template<indirectly_swappable<_Iter> _It2>
220 : friend _LIBCPP_HIDE_FROM_ABI constexpr
221 : void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y)
222 : noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
223 : {
224 : return ranges::iter_swap(__x.__current_, __y.__current_);
225 : }
226 : #endif // _LIBCPP_STD_VER > 17
227 :
228 : private:
229 : template<class _It2> friend class move_iterator;
230 :
231 : _Iter __current_;
232 : };
233 : _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator);
234 :
235 : template <class _Iter1, class _Iter2>
236 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
237 : bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
238 : {
239 : return __x.base() == __y.base();
240 : }
241 :
242 : #if _LIBCPP_STD_VER <= 17
243 : template <class _Iter1, class _Iter2>
244 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
245 : bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
246 : {
247 : return __x.base() != __y.base();
248 : }
249 : #endif // _LIBCPP_STD_VER <= 17
250 :
251 : template <class _Iter1, class _Iter2>
252 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
253 : bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
254 : {
255 : return __x.base() < __y.base();
256 : }
257 :
258 : template <class _Iter1, class _Iter2>
259 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
260 : bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
261 : {
262 : return __x.base() > __y.base();
263 : }
264 :
265 : template <class _Iter1, class _Iter2>
266 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
267 : bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
268 : {
269 : return __x.base() <= __y.base();
270 : }
271 :
272 : template <class _Iter1, class _Iter2>
273 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
274 : bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
275 : {
276 : return __x.base() >= __y.base();
277 : }
278 :
279 : #if _LIBCPP_STD_VER > 17
280 : template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
281 : inline _LIBCPP_HIDE_FROM_ABI constexpr
282 : auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
283 : -> compare_three_way_result_t<_Iter1, _Iter2>
284 : {
285 : return __x.base() <=> __y.base();
286 : }
287 : #endif // _LIBCPP_STD_VER > 17
288 :
289 : #ifndef _LIBCPP_CXX03_LANG
290 : template <class _Iter1, class _Iter2>
291 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
292 : auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
293 : -> decltype(__x.base() - __y.base())
294 : {
295 : return __x.base() - __y.base();
296 : }
297 : #else
298 : template <class _Iter1, class _Iter2>
299 : inline _LIBCPP_HIDE_FROM_ABI
300 : typename move_iterator<_Iter1>::difference_type
301 0 : operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
302 : {
303 0 : return __x.base() - __y.base();
304 : }
305 : #endif // !_LIBCPP_CXX03_LANG
306 :
307 : #if _LIBCPP_STD_VER > 17
308 : template <class _Iter>
309 : inline _LIBCPP_HIDE_FROM_ABI constexpr
310 : move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
311 : requires requires { { __x.base() + __n } -> same_as<_Iter>; }
312 : {
313 : return __x + __n;
314 : }
315 : #else
316 : template <class _Iter>
317 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
318 : move_iterator<_Iter>
319 : operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
320 : {
321 : return move_iterator<_Iter>(__x.base() + __n);
322 : }
323 : #endif // _LIBCPP_STD_VER > 17
324 :
325 : template <class _Iter>
326 : inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
327 : move_iterator<_Iter>
328 : make_move_iterator(_Iter __i)
329 : {
330 : return move_iterator<_Iter>(std::move(__i));
331 : }
332 :
333 : _LIBCPP_END_NAMESPACE_STD
334 :
335 : #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H
|