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 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} 100 101 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 102 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 _Iter base() const { return __current_; } 166 167 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 168 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 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_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 336