176d0caaeSpatrick // -*- C++ -*- 276d0caaeSpatrick //===----------------------------------------------------------------------===// 376d0caaeSpatrick // 476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information. 676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 776d0caaeSpatrick // 876d0caaeSpatrick //===----------------------------------------------------------------------===// 976d0caaeSpatrick 1076d0caaeSpatrick #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H 1176d0caaeSpatrick #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H 1276d0caaeSpatrick 13*4bdff4beSrobert #include <__compare/compare_three_way_result.h> 14*4bdff4beSrobert #include <__compare/three_way_comparable.h> 15*4bdff4beSrobert #include <__concepts/assignable.h> 16*4bdff4beSrobert #include <__concepts/convertible_to.h> 17*4bdff4beSrobert #include <__concepts/derived_from.h> 18*4bdff4beSrobert #include <__concepts/same_as.h> 1976d0caaeSpatrick #include <__config> 20*4bdff4beSrobert #include <__iterator/concepts.h> 21*4bdff4beSrobert #include <__iterator/incrementable_traits.h> 22*4bdff4beSrobert #include <__iterator/iter_move.h> 23*4bdff4beSrobert #include <__iterator/iter_swap.h> 2476d0caaeSpatrick #include <__iterator/iterator_traits.h> 25*4bdff4beSrobert #include <__iterator/move_sentinel.h> 26*4bdff4beSrobert #include <__iterator/readable_traits.h> 27*4bdff4beSrobert #include <__type_traits/conditional.h> 28*4bdff4beSrobert #include <__type_traits/enable_if.h> 29*4bdff4beSrobert #include <__type_traits/is_assignable.h> 30*4bdff4beSrobert #include <__type_traits/is_constructible.h> 31*4bdff4beSrobert #include <__type_traits/is_convertible.h> 32*4bdff4beSrobert #include <__type_traits/is_reference.h> 33*4bdff4beSrobert #include <__type_traits/is_same.h> 34*4bdff4beSrobert #include <__type_traits/remove_reference.h> 35*4bdff4beSrobert #include <__utility/declval.h> 36*4bdff4beSrobert #include <__utility/move.h> 3776d0caaeSpatrick 3876d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 3976d0caaeSpatrick # pragma GCC system_header 4076d0caaeSpatrick #endif 4176d0caaeSpatrick 4276d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD 4376d0caaeSpatrick 44*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 45*4bdff4beSrobert template<class _Iter, class = void> 46*4bdff4beSrobert struct __move_iter_category_base {}; 47*4bdff4beSrobert 48*4bdff4beSrobert template<class _Iter> 49*4bdff4beSrobert requires requires { typename iterator_traits<_Iter>::iterator_category; } 50*4bdff4beSrobert struct __move_iter_category_base<_Iter> { 51*4bdff4beSrobert using iterator_category = _If< 52*4bdff4beSrobert derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>, 53*4bdff4beSrobert random_access_iterator_tag, 54*4bdff4beSrobert typename iterator_traits<_Iter>::iterator_category 55*4bdff4beSrobert >; 56*4bdff4beSrobert }; 57*4bdff4beSrobert 58*4bdff4beSrobert template<class _Iter, class _Sent> 59*4bdff4beSrobert concept __move_iter_comparable = requires { 60*4bdff4beSrobert { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>; 61*4bdff4beSrobert }; 62*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 63*4bdff4beSrobert 6476d0caaeSpatrick template <class _Iter> 6576d0caaeSpatrick class _LIBCPP_TEMPLATE_VIS move_iterator 66*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 67*4bdff4beSrobert : public __move_iter_category_base<_Iter> 68*4bdff4beSrobert #endif 6976d0caaeSpatrick { 7076d0caaeSpatrick public: 71*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 72*4bdff4beSrobert using iterator_type = _Iter; 73*4bdff4beSrobert using iterator_concept = input_iterator_tag; 74*4bdff4beSrobert // iterator_category is inherited and not always present 75*4bdff4beSrobert using value_type = iter_value_t<_Iter>; 76*4bdff4beSrobert using difference_type = iter_difference_t<_Iter>; 77*4bdff4beSrobert using pointer = _Iter; 78*4bdff4beSrobert using reference = iter_rvalue_reference_t<_Iter>; 79*4bdff4beSrobert #else 8076d0caaeSpatrick typedef _Iter iterator_type; 81*4bdff4beSrobert typedef _If< 82*4bdff4beSrobert __is_cpp17_random_access_iterator<_Iter>::value, 83*4bdff4beSrobert random_access_iterator_tag, 84*4bdff4beSrobert typename iterator_traits<_Iter>::iterator_category 85*4bdff4beSrobert > iterator_category; 8676d0caaeSpatrick typedef typename iterator_traits<iterator_type>::value_type value_type; 8776d0caaeSpatrick typedef typename iterator_traits<iterator_type>::difference_type difference_type; 8876d0caaeSpatrick typedef iterator_type pointer; 8976d0caaeSpatrick 9076d0caaeSpatrick typedef typename iterator_traits<iterator_type>::reference __reference; 9176d0caaeSpatrick typedef typename conditional< 9276d0caaeSpatrick is_reference<__reference>::value, 93*4bdff4beSrobert __libcpp_remove_reference_t<__reference>&&, 9476d0caaeSpatrick __reference 9576d0caaeSpatrick >::type reference; 96*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 9776d0caaeSpatrick 98*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 99*4bdff4beSrobert explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} 10076d0caaeSpatrick 101*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 102*4bdff4beSrobert move_iterator& operator++() { ++__current_; return *this; } 10376d0caaeSpatrick 104*4bdff4beSrobert _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 105*4bdff4beSrobert pointer operator->() const { return __current_; } 10676d0caaeSpatrick 107*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 108*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr 109*4bdff4beSrobert move_iterator() requires is_constructible_v<_Iter> : __current_() {} 110*4bdff4beSrobert 111*4bdff4beSrobert template <class _Up> 112*4bdff4beSrobert requires (!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> 113*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr 114*4bdff4beSrobert move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} 115*4bdff4beSrobert 116*4bdff4beSrobert template <class _Up> 117*4bdff4beSrobert requires (!_IsSame<_Up, _Iter>::value) && 118*4bdff4beSrobert convertible_to<const _Up&, _Iter> && 119*4bdff4beSrobert assignable_from<_Iter&, const _Up&> 120*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr 12176d0caaeSpatrick move_iterator& operator=(const move_iterator<_Up>& __u) { 122*4bdff4beSrobert __current_ = __u.base(); 12376d0caaeSpatrick return *this; 12476d0caaeSpatrick } 12576d0caaeSpatrick 126*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } 127*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } 12876d0caaeSpatrick 129*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr 130*4bdff4beSrobert reference operator*() const { return ranges::iter_move(__current_); } 131*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr 132*4bdff4beSrobert reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } 133*4bdff4beSrobert 134*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr 135*4bdff4beSrobert auto operator++(int) 136*4bdff4beSrobert requires forward_iterator<_Iter> 137*4bdff4beSrobert { 138*4bdff4beSrobert move_iterator __tmp(*this); ++__current_; return __tmp; 139*4bdff4beSrobert } 140*4bdff4beSrobert 141*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr 142*4bdff4beSrobert void operator++(int) { ++__current_; } 143*4bdff4beSrobert #else 144*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 145*4bdff4beSrobert move_iterator() : __current_() {} 146*4bdff4beSrobert 147*4bdff4beSrobert template <class _Up, class = __enable_if_t< 148*4bdff4beSrobert !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value 149*4bdff4beSrobert > > 150*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 151*4bdff4beSrobert move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} 152*4bdff4beSrobert 153*4bdff4beSrobert template <class _Up, class = __enable_if_t< 154*4bdff4beSrobert !is_same<_Up, _Iter>::value && 155*4bdff4beSrobert is_convertible<const _Up&, _Iter>::value && 156*4bdff4beSrobert is_assignable<_Iter&, const _Up&>::value 157*4bdff4beSrobert > > 158*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 159*4bdff4beSrobert move_iterator& operator=(const move_iterator<_Up>& __u) { 160*4bdff4beSrobert __current_ = __u.base(); 161*4bdff4beSrobert return *this; 162*4bdff4beSrobert } 163*4bdff4beSrobert 164*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 165*4bdff4beSrobert _Iter base() const { return __current_; } 166*4bdff4beSrobert 167*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 168*4bdff4beSrobert reference operator*() const { return static_cast<reference>(*__current_); } 169*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 170*4bdff4beSrobert reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); } 171*4bdff4beSrobert 172*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 173*4bdff4beSrobert move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } 174*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 175*4bdff4beSrobert 176*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 177*4bdff4beSrobert move_iterator& operator--() { --__current_; return *this; } 178*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 179*4bdff4beSrobert move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } 180*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 181*4bdff4beSrobert move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } 182*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 183*4bdff4beSrobert move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } 184*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 185*4bdff4beSrobert move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } 186*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 187*4bdff4beSrobert move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } 188*4bdff4beSrobert 189*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 190*4bdff4beSrobert template<sentinel_for<_Iter> _Sent> 191*4bdff4beSrobert friend _LIBCPP_HIDE_FROM_ABI constexpr 192*4bdff4beSrobert bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) 193*4bdff4beSrobert requires __move_iter_comparable<_Iter, _Sent> 19476d0caaeSpatrick { 19576d0caaeSpatrick return __x.base() == __y.base(); 19676d0caaeSpatrick } 19776d0caaeSpatrick 198*4bdff4beSrobert template<sized_sentinel_for<_Iter> _Sent> 199*4bdff4beSrobert friend _LIBCPP_HIDE_FROM_ABI constexpr 200*4bdff4beSrobert iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) 201*4bdff4beSrobert { 202*4bdff4beSrobert return __x.base() - __y.base(); 203*4bdff4beSrobert } 204*4bdff4beSrobert 205*4bdff4beSrobert template<sized_sentinel_for<_Iter> _Sent> 206*4bdff4beSrobert friend _LIBCPP_HIDE_FROM_ABI constexpr 207*4bdff4beSrobert iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) 208*4bdff4beSrobert { 209*4bdff4beSrobert return __x.base() - __y.base(); 210*4bdff4beSrobert } 211*4bdff4beSrobert 212*4bdff4beSrobert friend _LIBCPP_HIDE_FROM_ABI constexpr 213*4bdff4beSrobert iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) 214*4bdff4beSrobert noexcept(noexcept(ranges::iter_move(__i.__current_))) 215*4bdff4beSrobert { 216*4bdff4beSrobert return ranges::iter_move(__i.__current_); 217*4bdff4beSrobert } 218*4bdff4beSrobert 219*4bdff4beSrobert template<indirectly_swappable<_Iter> _It2> 220*4bdff4beSrobert friend _LIBCPP_HIDE_FROM_ABI constexpr 221*4bdff4beSrobert void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) 222*4bdff4beSrobert noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) 223*4bdff4beSrobert { 224*4bdff4beSrobert return ranges::iter_swap(__x.__current_, __y.__current_); 225*4bdff4beSrobert } 226*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 227*4bdff4beSrobert 228*4bdff4beSrobert private: 229*4bdff4beSrobert template<class _It2> friend class move_iterator; 230*4bdff4beSrobert 231*4bdff4beSrobert _Iter __current_; 232*4bdff4beSrobert }; 233*4bdff4beSrobert _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); 234*4bdff4beSrobert 23576d0caaeSpatrick template <class _Iter1, class _Iter2> 236*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 237*4bdff4beSrobert bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 238*4bdff4beSrobert { 239*4bdff4beSrobert return __x.base() == __y.base(); 240*4bdff4beSrobert } 241*4bdff4beSrobert 242*4bdff4beSrobert #if _LIBCPP_STD_VER <= 17 243*4bdff4beSrobert template <class _Iter1, class _Iter2> 244*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 245*4bdff4beSrobert bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 246*4bdff4beSrobert { 247*4bdff4beSrobert return __x.base() != __y.base(); 248*4bdff4beSrobert } 249*4bdff4beSrobert #endif // _LIBCPP_STD_VER <= 17 250*4bdff4beSrobert 251*4bdff4beSrobert template <class _Iter1, class _Iter2> 252*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 253*4bdff4beSrobert bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 25476d0caaeSpatrick { 25576d0caaeSpatrick return __x.base() < __y.base(); 25676d0caaeSpatrick } 25776d0caaeSpatrick 25876d0caaeSpatrick template <class _Iter1, class _Iter2> 259*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 260*4bdff4beSrobert bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 26176d0caaeSpatrick { 26276d0caaeSpatrick return __x.base() > __y.base(); 26376d0caaeSpatrick } 26476d0caaeSpatrick 26576d0caaeSpatrick template <class _Iter1, class _Iter2> 266*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 267*4bdff4beSrobert bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 26876d0caaeSpatrick { 26976d0caaeSpatrick return __x.base() <= __y.base(); 27076d0caaeSpatrick } 27176d0caaeSpatrick 272*4bdff4beSrobert template <class _Iter1, class _Iter2> 273*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 274*4bdff4beSrobert bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 275*4bdff4beSrobert { 276*4bdff4beSrobert return __x.base() >= __y.base(); 277*4bdff4beSrobert } 278*4bdff4beSrobert 279*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 280*4bdff4beSrobert template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> 281*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI constexpr 282*4bdff4beSrobert auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 283*4bdff4beSrobert -> compare_three_way_result_t<_Iter1, _Iter2> 284*4bdff4beSrobert { 285*4bdff4beSrobert return __x.base() <=> __y.base(); 286*4bdff4beSrobert } 287*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 288*4bdff4beSrobert 28976d0caaeSpatrick #ifndef _LIBCPP_CXX03_LANG 29076d0caaeSpatrick template <class _Iter1, class _Iter2> 291*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 292*4bdff4beSrobert auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 29376d0caaeSpatrick -> decltype(__x.base() - __y.base()) 29476d0caaeSpatrick { 29576d0caaeSpatrick return __x.base() - __y.base(); 29676d0caaeSpatrick } 29776d0caaeSpatrick #else 29876d0caaeSpatrick template <class _Iter1, class _Iter2> 299*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI 30076d0caaeSpatrick typename move_iterator<_Iter1>::difference_type 30176d0caaeSpatrick operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 30276d0caaeSpatrick { 30376d0caaeSpatrick return __x.base() - __y.base(); 30476d0caaeSpatrick } 305*4bdff4beSrobert #endif // !_LIBCPP_CXX03_LANG 30676d0caaeSpatrick 307*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 30876d0caaeSpatrick template <class _Iter> 309*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI constexpr 310*4bdff4beSrobert move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) 311*4bdff4beSrobert requires requires { { __x.base() + __n } -> same_as<_Iter>; } 312*4bdff4beSrobert { 313*4bdff4beSrobert return __x + __n; 314*4bdff4beSrobert } 315*4bdff4beSrobert #else 316*4bdff4beSrobert template <class _Iter> 317*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 31876d0caaeSpatrick move_iterator<_Iter> 31976d0caaeSpatrick operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) 32076d0caaeSpatrick { 32176d0caaeSpatrick return move_iterator<_Iter>(__x.base() + __n); 32276d0caaeSpatrick } 323*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 32476d0caaeSpatrick 32576d0caaeSpatrick template <class _Iter> 326*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 32776d0caaeSpatrick move_iterator<_Iter> 32876d0caaeSpatrick make_move_iterator(_Iter __i) 32976d0caaeSpatrick { 330*4bdff4beSrobert return move_iterator<_Iter>(std::move(__i)); 33176d0caaeSpatrick } 33276d0caaeSpatrick 33376d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD 33476d0caaeSpatrick 33576d0caaeSpatrick #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H 336