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 <__utility/move.h> 28 #include <type_traits> 29 30 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 31 # pragma GCC system_header 32 #endif 33 34 _LIBCPP_BEGIN_NAMESPACE_STD 35 36 #if _LIBCPP_STD_VER > 17 37 template<class _Iter, class = void> 38 struct __move_iter_category_base {}; 39 40 template<class _Iter> 41 requires requires { typename iterator_traits<_Iter>::iterator_category; } 42 struct __move_iter_category_base<_Iter> { 43 using iterator_category = _If< 44 derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>, 45 random_access_iterator_tag, 46 typename iterator_traits<_Iter>::iterator_category 47 >; 48 }; 49 50 template<class _Iter, class _Sent> 51 concept __move_iter_comparable = requires { 52 { declval<const _Iter&>() == declval<_Sent>() } -> convertible_to<bool>; 53 }; 54 #endif // _LIBCPP_STD_VER > 17 55 56 template <class _Iter> 57 class _LIBCPP_TEMPLATE_VIS move_iterator 58 #if _LIBCPP_STD_VER > 17 59 : public __move_iter_category_base<_Iter> 60 #endif 61 { 62 public: 63 #if _LIBCPP_STD_VER > 17 64 using iterator_type = _Iter; 65 using iterator_concept = input_iterator_tag; 66 // iterator_category is inherited and not always present 67 using value_type = iter_value_t<_Iter>; 68 using difference_type = iter_difference_t<_Iter>; 69 using pointer = _Iter; 70 using reference = iter_rvalue_reference_t<_Iter>; 71 #else 72 typedef _Iter iterator_type; 73 typedef _If< 74 __is_cpp17_random_access_iterator<_Iter>::value, 75 random_access_iterator_tag, 76 typename iterator_traits<_Iter>::iterator_category 77 > iterator_category; 78 typedef typename iterator_traits<iterator_type>::value_type value_type; 79 typedef typename iterator_traits<iterator_type>::difference_type difference_type; 80 typedef iterator_type pointer; 81 82 #ifndef _LIBCPP_CXX03_LANG 83 typedef typename iterator_traits<iterator_type>::reference __reference; 84 typedef typename conditional< 85 is_reference<__reference>::value, 86 typename remove_reference<__reference>::type&&, 87 __reference 88 >::type reference; 89 #else 90 typedef typename iterator_traits<iterator_type>::reference reference; 91 #endif 92 93 #endif // _LIBCPP_STD_VER > 17 94 95 #if _LIBCPP_STD_VER > 17 96 _LIBCPP_HIDE_FROM_ABI constexpr 97 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} 98 99 _LIBCPP_HIDE_FROM_ABI constexpr 100 move_iterator() requires is_constructible_v<_Iter> : __current_() {} 101 102 template <class _Up> 103 requires (!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> 104 _LIBCPP_HIDE_FROM_ABI constexpr 105 move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} 106 107 template <class _Up> 108 requires (!_IsSame<_Up, _Iter>::value) && 109 convertible_to<const _Up&, _Iter> && 110 assignable_from<_Iter&, const _Up&> 111 _LIBCPP_HIDE_FROM_ABI constexpr 112 move_iterator& operator=(const move_iterator<_Up>& __u) { 113 __current_ = __u.base(); 114 return *this; 115 } 116 117 _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } 118 _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } 119 120 _LIBCPP_HIDE_FROM_ABI constexpr 121 reference operator*() const { return ranges::iter_move(__current_); } 122 _LIBCPP_HIDE_FROM_ABI constexpr 123 reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } 124 125 _LIBCPP_HIDE_FROM_ABI constexpr 126 move_iterator& operator++() { ++__current_; return *this; } 127 128 _LIBCPP_HIDE_FROM_ABI constexpr 129 auto operator++(int) 130 requires forward_iterator<_Iter> 131 { 132 move_iterator __tmp(*this); ++__current_; return __tmp; 133 } 134 135 _LIBCPP_HIDE_FROM_ABI constexpr 136 void operator++(int) { ++__current_; } 137 #else 138 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 139 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} 140 141 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 142 move_iterator() : __current_() {} 143 144 template <class _Up, class = __enable_if_t< 145 !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value 146 > > 147 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 148 move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} 149 150 template <class _Up, class = __enable_if_t< 151 !is_same<_Up, _Iter>::value && 152 is_convertible<const _Up&, _Iter>::value && 153 is_assignable<_Iter&, const _Up&>::value 154 > > 155 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 156 move_iterator& operator=(const move_iterator<_Up>& __u) { 157 __current_ = __u.base(); 158 return *this; 159 } 160 161 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 162 _Iter base() const { return __current_; } 163 164 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 165 reference operator*() const { return static_cast<reference>(*__current_); } 166 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 167 pointer operator->() const { return __current_; } 168 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 169 reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); } 170 171 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 172 move_iterator& operator++() { ++__current_; return *this; } 173 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 174 move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } 175 #endif // _LIBCPP_STD_VER > 17 176 177 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 178 move_iterator& operator--() { --__current_; return *this; } 179 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 180 move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } 181 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 182 move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } 183 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 184 move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } 185 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 186 move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } 187 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 188 move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } 189 190 #if _LIBCPP_STD_VER > 17 191 template<sentinel_for<_Iter> _Sent> 192 friend _LIBCPP_HIDE_FROM_ABI constexpr 193 bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) 194 requires __move_iter_comparable<_Iter, _Sent> 195 { 196 return __x.base() == __y.base(); 197 } 198 199 template<sized_sentinel_for<_Iter> _Sent> 200 friend _LIBCPP_HIDE_FROM_ABI constexpr 201 iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) 202 { 203 return __x.base() - __y.base(); 204 } 205 206 template<sized_sentinel_for<_Iter> _Sent> 207 friend _LIBCPP_HIDE_FROM_ABI constexpr 208 iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) 209 { 210 return __x.base() - __y.base(); 211 } 212 213 friend _LIBCPP_HIDE_FROM_ABI constexpr 214 iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) 215 noexcept(noexcept(ranges::iter_move(__i.__current_))) 216 { 217 return ranges::iter_move(__i.__current_); 218 } 219 220 template<indirectly_swappable<_Iter> _It2> 221 friend _LIBCPP_HIDE_FROM_ABI constexpr 222 void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) 223 noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) 224 { 225 return ranges::iter_swap(__x.__current_, __y.__current_); 226 } 227 #endif // _LIBCPP_STD_VER > 17 228 229 private: 230 template<class _It2> friend class move_iterator; 231 232 _Iter __current_; 233 }; 234 235 template <class _Iter1, class _Iter2> 236 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 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_AFTER_CXX14 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_AFTER_CXX14 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_AFTER_CXX14 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_AFTER_CXX14 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_AFTER_CXX14 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_AFTER_CXX14 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 operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 302 { 303 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_AFTER_CXX14 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_AFTER_CXX14 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 336