Warning: This file is not a C or C++ file. It does not have highlighting.
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_PUSH_MACROS |
43 | #include <__undef_macros> |
44 | |
45 | _LIBCPP_BEGIN_NAMESPACE_STD |
46 | |
47 | #if _LIBCPP_STD_VER >= 20 |
48 | template <class _Iter, class = void> |
49 | struct __move_iter_category_base {}; |
50 | |
51 | template <class _Iter> |
52 | requires requires { typename iterator_traits<_Iter>::iterator_category; } |
53 | struct __move_iter_category_base<_Iter> { |
54 | using iterator_category = |
55 | _If< derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>, |
56 | random_access_iterator_tag, |
57 | typename iterator_traits<_Iter>::iterator_category >; |
58 | }; |
59 | |
60 | template <class _Iter, class _Sent> |
61 | concept __move_iter_comparable = requires { |
62 | { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>; |
63 | }; |
64 | #endif // _LIBCPP_STD_VER >= 20 |
65 | |
66 | template <class _Iter> |
67 | class move_iterator |
68 | #if _LIBCPP_STD_VER >= 20 |
69 | : public __move_iter_category_base<_Iter> |
70 | #endif |
71 | { |
72 | #if _LIBCPP_STD_VER >= 20 |
73 | |
74 | private: |
75 | _LIBCPP_HIDE_FROM_ABI static constexpr auto __get_iter_concept() { |
76 | if constexpr (random_access_iterator<_Iter>) { |
77 | return random_access_iterator_tag{}; |
78 | } else if constexpr (bidirectional_iterator<_Iter>) { |
79 | return bidirectional_iterator_tag{}; |
80 | } else if constexpr (forward_iterator<_Iter>) { |
81 | return forward_iterator_tag{}; |
82 | } else { |
83 | return input_iterator_tag{}; |
84 | } |
85 | } |
86 | #endif // _LIBCPP_STD_VER >= 20 |
87 | |
88 | public: |
89 | #if _LIBCPP_STD_VER >= 20 |
90 | using iterator_type = _Iter; |
91 | using iterator_concept = decltype(__get_iter_concept()); |
92 | // iterator_category is inherited and not always present |
93 | using value_type = iter_value_t<_Iter>; |
94 | using difference_type = iter_difference_t<_Iter>; |
95 | using pointer = _Iter; |
96 | using reference = iter_rvalue_reference_t<_Iter>; |
97 | #else |
98 | typedef _Iter iterator_type; |
99 | typedef _If< __has_random_access_iterator_category<_Iter>::value, |
100 | random_access_iterator_tag, |
101 | typename iterator_traits<_Iter>::iterator_category > |
102 | iterator_category; |
103 | typedef typename iterator_traits<iterator_type>::value_type value_type; |
104 | typedef typename iterator_traits<iterator_type>::difference_type difference_type; |
105 | typedef iterator_type pointer; |
106 | |
107 | typedef typename iterator_traits<iterator_type>::reference __reference; |
108 | typedef __conditional_t<is_reference<__reference>::value, __libcpp_remove_reference_t<__reference>&&, __reference> |
109 | reference; |
110 | #endif // _LIBCPP_STD_VER >= 20 |
111 | |
112 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} |
113 | |
114 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator++() { |
115 | ++__current_; |
116 | return *this; |
117 | } |
118 | |
119 | _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const { |
120 | return __current_; |
121 | } |
122 | |
123 | #if _LIBCPP_STD_VER >= 20 |
124 | _LIBCPP_HIDE_FROM_ABI constexpr move_iterator() |
125 | requires is_constructible_v<_Iter> |
126 | : __current_() {} |
127 | |
128 | template <class _Up> |
129 | requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> |
130 | _LIBCPP_HIDE_FROM_ABI constexpr move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} |
131 | |
132 | template <class _Up> |
133 | requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> && assignable_from<_Iter&, const _Up&> |
134 | _LIBCPP_HIDE_FROM_ABI constexpr move_iterator& operator=(const move_iterator<_Up>& __u) { |
135 | __current_ = __u.base(); |
136 | return *this; |
137 | } |
138 | |
139 | _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; } |
140 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } |
141 | |
142 | _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return ranges::iter_move(__current_); } |
143 | _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const { |
144 | return ranges::iter_move(__current_ + __n); |
145 | } |
146 | |
147 | _LIBCPP_HIDE_FROM_ABI constexpr auto operator++(int) |
148 | requires forward_iterator<_Iter> |
149 | { |
150 | move_iterator __tmp(*this); |
151 | ++__current_; |
152 | return __tmp; |
153 | } |
154 | |
155 | _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; } |
156 | #else |
157 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator() : __current_() {} |
158 | |
159 | template <class _Up, __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value, int> = 0> |
160 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator(const move_iterator<_Up>& __u) |
161 | : __current_(__u.base()) {} |
162 | |
163 | template <class _Up, |
164 | __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value && |
165 | is_assignable<_Iter&, const _Up&>::value, |
166 | int> = 0> |
167 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator=(const move_iterator<_Up>& __u) { |
168 | __current_ = __u.base(); |
169 | return *this; |
170 | } |
171 | |
172 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return __current_; } |
173 | |
174 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const { |
175 | return static_cast<reference>(*__current_); |
176 | } |
177 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const { |
178 | return static_cast<reference>(__current_[__n]); |
179 | } |
180 | |
181 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator++(int) { |
182 | move_iterator __tmp(*this); |
183 | ++__current_; |
184 | return __tmp; |
185 | } |
186 | #endif // _LIBCPP_STD_VER >= 20 |
187 | |
188 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator--() { |
189 | --__current_; |
190 | return *this; |
191 | } |
192 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator--(int) { |
193 | move_iterator __tmp(*this); |
194 | --__current_; |
195 | return __tmp; |
196 | } |
197 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator+(difference_type __n) const { |
198 | return move_iterator(__current_ + __n); |
199 | } |
200 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator+=(difference_type __n) { |
201 | __current_ += __n; |
202 | return *this; |
203 | } |
204 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator-(difference_type __n) const { |
205 | return move_iterator(__current_ - __n); |
206 | } |
207 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator-=(difference_type __n) { |
208 | __current_ -= __n; |
209 | return *this; |
210 | } |
211 | |
212 | #if _LIBCPP_STD_VER >= 20 |
213 | template <sentinel_for<_Iter> _Sent> |
214 | friend _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) |
215 | requires __move_iter_comparable<_Iter, _Sent> |
216 | { |
217 | return __x.base() == __y.base(); |
218 | } |
219 | |
220 | template <sized_sentinel_for<_Iter> _Sent> |
221 | friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> |
222 | operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) { |
223 | return __x.base() - __y.base(); |
224 | } |
225 | |
226 | template <sized_sentinel_for<_Iter> _Sent> |
227 | friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> |
228 | operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) { |
229 | return __x.base() - __y.base(); |
230 | } |
231 | |
232 | friend _LIBCPP_HIDE_FROM_ABI constexpr iter_rvalue_reference_t<_Iter> |
233 | iter_move(const move_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) { |
234 | return ranges::iter_move(__i.__current_); |
235 | } |
236 | |
237 | template <indirectly_swappable<_Iter> _It2> |
238 | friend _LIBCPP_HIDE_FROM_ABI constexpr void |
239 | iter_swap(const move_iterator& __x, |
240 | const move_iterator<_It2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) { |
241 | return ranges::iter_swap(__x.__current_, __y.__current_); |
242 | } |
243 | #endif // _LIBCPP_STD_VER >= 20 |
244 | |
245 | private: |
246 | template <class _It2> |
247 | friend class move_iterator; |
248 | |
249 | _Iter __current_; |
250 | }; |
251 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); |
252 | |
253 | template <class _Iter1, class _Iter2> |
254 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool |
255 | operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { |
256 | return __x.base() == __y.base(); |
257 | } |
258 | |
259 | #if _LIBCPP_STD_VER <= 17 |
260 | template <class _Iter1, class _Iter2> |
261 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool |
262 | operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { |
263 | return __x.base() != __y.base(); |
264 | } |
265 | #endif // _LIBCPP_STD_VER <= 17 |
266 | |
267 | template <class _Iter1, class _Iter2> |
268 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool |
269 | operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { |
270 | return __x.base() < __y.base(); |
271 | } |
272 | |
273 | template <class _Iter1, class _Iter2> |
274 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool |
275 | operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { |
276 | return __x.base() > __y.base(); |
277 | } |
278 | |
279 | template <class _Iter1, class _Iter2> |
280 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool |
281 | operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { |
282 | return __x.base() <= __y.base(); |
283 | } |
284 | |
285 | template <class _Iter1, class _Iter2> |
286 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool |
287 | operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { |
288 | return __x.base() >= __y.base(); |
289 | } |
290 | |
291 | #if _LIBCPP_STD_VER >= 20 |
292 | template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> |
293 | inline _LIBCPP_HIDE_FROM_ABI constexpr auto |
294 | operator<=>(const move_iterator<_Iter1>& __x, |
295 | const move_iterator<_Iter2>& __y) -> compare_three_way_result_t<_Iter1, _Iter2> { |
296 | return __x.base() <=> __y.base(); |
297 | } |
298 | #endif // _LIBCPP_STD_VER >= 20 |
299 | |
300 | #ifndef _LIBCPP_CXX03_LANG |
301 | template <class _Iter1, class _Iter2> |
302 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto |
303 | operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -> decltype(__x.base() - __y.base()) { |
304 | return __x.base() - __y.base(); |
305 | } |
306 | #else |
307 | template <class _Iter1, class _Iter2> |
308 | inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type |
309 | operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { |
310 | return __x.base() - __y.base(); |
311 | } |
312 | #endif // !_LIBCPP_CXX03_LANG |
313 | |
314 | #if _LIBCPP_STD_VER >= 20 |
315 | template <class _Iter> |
316 | inline _LIBCPP_HIDE_FROM_ABI constexpr move_iterator<_Iter> |
317 | operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) |
318 | requires requires { |
319 | { __x.base() + __n } -> same_as<_Iter>; |
320 | } |
321 | { |
322 | return __x + __n; |
323 | } |
324 | #else |
325 | template <class _Iter> |
326 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> |
327 | operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { |
328 | return move_iterator<_Iter>(__x.base() + __n); |
329 | } |
330 | #endif // _LIBCPP_STD_VER >= 20 |
331 | |
332 | #if _LIBCPP_STD_VER >= 20 |
333 | template <class _Iter1, class _Iter2> |
334 | requires(!sized_sentinel_for<_Iter1, _Iter2>) |
335 | inline constexpr bool disable_sized_sentinel_for<move_iterator<_Iter1>, move_iterator<_Iter2>> = true; |
336 | #endif // _LIBCPP_STD_VER >= 20 |
337 | |
338 | template <class _Iter> |
339 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> make_move_iterator(_Iter __i) { |
340 | return move_iterator<_Iter>(std::move(__i)); |
341 | } |
342 | |
343 | _LIBCPP_END_NAMESPACE_STD |
344 | |
345 | _LIBCPP_POP_MACROS |
346 | |
347 | #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H |
348 |
Warning: This file is not a C or C++ file. It does not have highlighting.