1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H 11fe6060f1SDimitry Andric #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H 12fe6060f1SDimitry Andric 1381ad6265SDimitry Andric #include <__compare/compare_three_way_result.h> 1481ad6265SDimitry Andric #include <__compare/three_way_comparable.h> 1581ad6265SDimitry Andric #include <__concepts/assignable.h> 1681ad6265SDimitry Andric #include <__concepts/convertible_to.h> 1781ad6265SDimitry Andric #include <__concepts/derived_from.h> 1881ad6265SDimitry Andric #include <__concepts/same_as.h> 19fe6060f1SDimitry Andric #include <__config> 2081ad6265SDimitry Andric #include <__iterator/concepts.h> 2181ad6265SDimitry Andric #include <__iterator/incrementable_traits.h> 2281ad6265SDimitry Andric #include <__iterator/iter_move.h> 2381ad6265SDimitry Andric #include <__iterator/iter_swap.h> 24fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 2581ad6265SDimitry Andric #include <__iterator/move_sentinel.h> 2681ad6265SDimitry Andric #include <__iterator/readable_traits.h> 27bdd1243dSDimitry Andric #include <__type_traits/conditional.h> 28bdd1243dSDimitry Andric #include <__type_traits/enable_if.h> 29bdd1243dSDimitry Andric #include <__type_traits/is_assignable.h> 30bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h> 31bdd1243dSDimitry Andric #include <__type_traits/is_convertible.h> 32bdd1243dSDimitry Andric #include <__type_traits/is_reference.h> 33bdd1243dSDimitry Andric #include <__type_traits/is_same.h> 34bdd1243dSDimitry Andric #include <__type_traits/remove_reference.h> 35bdd1243dSDimitry Andric #include <__utility/declval.h> 3604eeddc0SDimitry Andric #include <__utility/move.h> 37fe6060f1SDimitry Andric 38fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 39fe6060f1SDimitry Andric # pragma GCC system_header 40fe6060f1SDimitry Andric #endif 41fe6060f1SDimitry Andric 4206c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 4306c3fb27SDimitry Andric #include <__undef_macros> 4406c3fb27SDimitry Andric 45fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 46fe6060f1SDimitry Andric 4706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 4881ad6265SDimitry Andric template <class _Iter, class = void> 4981ad6265SDimitry Andric struct __move_iter_category_base {}; 5081ad6265SDimitry Andric 5181ad6265SDimitry Andric template <class _Iter> 5281ad6265SDimitry Andric requires requires { typename iterator_traits<_Iter>::iterator_category; } 5381ad6265SDimitry Andric struct __move_iter_category_base<_Iter> { 54cb14a3feSDimitry Andric using iterator_category = 55cb14a3feSDimitry Andric _If< derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>, 5681ad6265SDimitry Andric random_access_iterator_tag, 57cb14a3feSDimitry Andric typename iterator_traits<_Iter>::iterator_category >; 5881ad6265SDimitry Andric }; 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric template <class _Iter, class _Sent> 6181ad6265SDimitry Andric concept __move_iter_comparable = requires { 62bdd1243dSDimitry Andric { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>; 6381ad6265SDimitry Andric }; 6406c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 6581ad6265SDimitry Andric 66fe6060f1SDimitry Andric template <class _Iter> 67fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS move_iterator 6806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 6981ad6265SDimitry Andric : public __move_iter_category_base<_Iter> 7081ad6265SDimitry Andric #endif 71fe6060f1SDimitry Andric { 7206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 73cb14a3feSDimitry Andric 7406c3fb27SDimitry Andric private: 75cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr auto __get_iter_concept() { 7606c3fb27SDimitry Andric if constexpr (random_access_iterator<_Iter>) { 7706c3fb27SDimitry Andric return random_access_iterator_tag{}; 7806c3fb27SDimitry Andric } else if constexpr (bidirectional_iterator<_Iter>) { 7906c3fb27SDimitry Andric return bidirectional_iterator_tag{}; 8006c3fb27SDimitry Andric } else if constexpr (forward_iterator<_Iter>) { 8106c3fb27SDimitry Andric return forward_iterator_tag{}; 8206c3fb27SDimitry Andric } else { 8306c3fb27SDimitry Andric return input_iterator_tag{}; 8406c3fb27SDimitry Andric } 8506c3fb27SDimitry Andric } 8606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 87cb14a3feSDimitry Andric 88fe6060f1SDimitry Andric public: 8906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 9081ad6265SDimitry Andric using iterator_type = _Iter; 9106c3fb27SDimitry Andric using iterator_concept = decltype(__get_iter_concept()); 9281ad6265SDimitry Andric // iterator_category is inherited and not always present 9381ad6265SDimitry Andric using value_type = iter_value_t<_Iter>; 9481ad6265SDimitry Andric using difference_type = iter_difference_t<_Iter>; 9581ad6265SDimitry Andric using pointer = _Iter; 9681ad6265SDimitry Andric using reference = iter_rvalue_reference_t<_Iter>; 9781ad6265SDimitry Andric #else 9804eeddc0SDimitry Andric typedef _Iter iterator_type; 99cb14a3feSDimitry Andric typedef _If< __has_random_access_iterator_category<_Iter>::value, 10004eeddc0SDimitry Andric random_access_iterator_tag, 101cb14a3feSDimitry Andric typename iterator_traits<_Iter>::iterator_category > 102cb14a3feSDimitry Andric iterator_category; 10304eeddc0SDimitry Andric typedef typename iterator_traits<iterator_type>::value_type value_type; 10404eeddc0SDimitry Andric typedef typename iterator_traits<iterator_type>::difference_type difference_type; 10504eeddc0SDimitry Andric typedef iterator_type pointer; 10604eeddc0SDimitry Andric 107fe6060f1SDimitry Andric typedef typename iterator_traits<iterator_type>::reference __reference; 108*0fca6ea1SDimitry Andric typedef __conditional_t<is_reference<__reference>::value, __libcpp_remove_reference_t<__reference>&&, __reference> 109*0fca6ea1SDimitry Andric reference; 11006c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 111fe6060f1SDimitry Andric 112cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} 11381ad6265SDimitry Andric 114cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator++() { 115cb14a3feSDimitry Andric ++__current_; 116cb14a3feSDimitry Andric return *this; 117cb14a3feSDimitry Andric } 11881ad6265SDimitry Andric 119cb14a3feSDimitry Andric _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const { 120cb14a3feSDimitry Andric return __current_; 121cb14a3feSDimitry Andric } 12281ad6265SDimitry Andric 12306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 124cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr move_iterator() 125cb14a3feSDimitry Andric requires is_constructible_v<_Iter> 126cb14a3feSDimitry Andric : __current_() {} 12781ad6265SDimitry Andric 12881ad6265SDimitry Andric template <class _Up> 12981ad6265SDimitry Andric requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> 130cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} 13181ad6265SDimitry Andric 13281ad6265SDimitry Andric template <class _Up> 133cb14a3feSDimitry Andric requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> && assignable_from<_Iter&, const _Up&> 134cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr move_iterator& operator=(const move_iterator<_Up>& __u) { 13581ad6265SDimitry Andric __current_ = __u.base(); 13681ad6265SDimitry Andric return *this; 13781ad6265SDimitry Andric } 13881ad6265SDimitry Andric 13981ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; } 14081ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } 14181ad6265SDimitry Andric 142cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return ranges::iter_move(__current_); } 143cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const { 144cb14a3feSDimitry Andric return ranges::iter_move(__current_ + __n); 14581ad6265SDimitry Andric } 14681ad6265SDimitry Andric 147cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto operator++(int) 148cb14a3feSDimitry Andric requires forward_iterator<_Iter> 149cb14a3feSDimitry Andric { 150cb14a3feSDimitry Andric move_iterator __tmp(*this); 151cb14a3feSDimitry Andric ++__current_; 152cb14a3feSDimitry Andric return __tmp; 153cb14a3feSDimitry Andric } 154cb14a3feSDimitry Andric 155cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; } 15681ad6265SDimitry Andric #else 157cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator() : __current_() {} 158fe6060f1SDimitry Andric 159*0fca6ea1SDimitry Andric template <class _Up, __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value, int> = 0> 160cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator(const move_iterator<_Up>& __u) 161cb14a3feSDimitry Andric : __current_(__u.base()) {} 162fe6060f1SDimitry Andric 163cb14a3feSDimitry Andric template <class _Up, 164*0fca6ea1SDimitry Andric __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value && 165*0fca6ea1SDimitry Andric is_assignable<_Iter&, const _Up&>::value, 166*0fca6ea1SDimitry Andric int> = 0> 167cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator=(const move_iterator<_Up>& __u) { 16804eeddc0SDimitry Andric __current_ = __u.base(); 169fe6060f1SDimitry Andric return *this; 170fe6060f1SDimitry Andric } 171fe6060f1SDimitry Andric 172cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return __current_; } 17304eeddc0SDimitry Andric 174cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const { 175cb14a3feSDimitry Andric return static_cast<reference>(*__current_); 176cb14a3feSDimitry Andric } 177cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const { 178cb14a3feSDimitry Andric return static_cast<reference>(__current_[__n]); 179cb14a3feSDimitry Andric } 18004eeddc0SDimitry Andric 181cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator++(int) { 182cb14a3feSDimitry Andric move_iterator __tmp(*this); 183cb14a3feSDimitry Andric ++__current_; 184cb14a3feSDimitry Andric return __tmp; 185cb14a3feSDimitry Andric } 18606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 18781ad6265SDimitry Andric 188cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator--() { 189cb14a3feSDimitry Andric --__current_; 190cb14a3feSDimitry Andric return *this; 191cb14a3feSDimitry Andric } 192cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator--(int) { 193cb14a3feSDimitry Andric move_iterator __tmp(*this); 194cb14a3feSDimitry Andric --__current_; 195cb14a3feSDimitry Andric return __tmp; 196cb14a3feSDimitry Andric } 197cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator+(difference_type __n) const { 198cb14a3feSDimitry Andric return move_iterator(__current_ + __n); 199cb14a3feSDimitry Andric } 200cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator+=(difference_type __n) { 201cb14a3feSDimitry Andric __current_ += __n; 202cb14a3feSDimitry Andric return *this; 203cb14a3feSDimitry Andric } 204cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator-(difference_type __n) const { 205cb14a3feSDimitry Andric return move_iterator(__current_ - __n); 206cb14a3feSDimitry Andric } 207cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator-=(difference_type __n) { 208cb14a3feSDimitry Andric __current_ -= __n; 209cb14a3feSDimitry Andric return *this; 210cb14a3feSDimitry Andric } 21104eeddc0SDimitry Andric 21206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 21381ad6265SDimitry Andric template <sentinel_for<_Iter> _Sent> 214cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) 21581ad6265SDimitry Andric requires __move_iter_comparable<_Iter, _Sent> 21681ad6265SDimitry Andric { 21781ad6265SDimitry Andric return __x.base() == __y.base(); 21881ad6265SDimitry Andric } 21981ad6265SDimitry Andric 22081ad6265SDimitry Andric template <sized_sentinel_for<_Iter> _Sent> 221cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> 222cb14a3feSDimitry Andric operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) { 22381ad6265SDimitry Andric return __x.base() - __y.base(); 22481ad6265SDimitry Andric } 22581ad6265SDimitry Andric 22681ad6265SDimitry Andric template <sized_sentinel_for<_Iter> _Sent> 227cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> 228cb14a3feSDimitry Andric operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) { 22981ad6265SDimitry Andric return __x.base() - __y.base(); 23081ad6265SDimitry Andric } 23181ad6265SDimitry Andric 232cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr iter_rvalue_reference_t<_Iter> 233cb14a3feSDimitry Andric iter_move(const move_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) { 23481ad6265SDimitry Andric return ranges::iter_move(__i.__current_); 23581ad6265SDimitry Andric } 23681ad6265SDimitry Andric 23781ad6265SDimitry Andric template <indirectly_swappable<_Iter> _It2> 238cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr void 239cb14a3feSDimitry Andric iter_swap(const move_iterator& __x, 240cb14a3feSDimitry Andric const move_iterator<_It2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) { 24181ad6265SDimitry Andric return ranges::iter_swap(__x.__current_, __y.__current_); 24281ad6265SDimitry Andric } 24306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 24481ad6265SDimitry Andric 24504eeddc0SDimitry Andric private: 246cb14a3feSDimitry Andric template <class _It2> 247cb14a3feSDimitry Andric friend class move_iterator; 24881ad6265SDimitry Andric 24904eeddc0SDimitry Andric _Iter __current_; 250fe6060f1SDimitry Andric }; 251bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); 252fe6060f1SDimitry Andric 253fe6060f1SDimitry Andric template <class _Iter1, class _Iter2> 254cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool 255cb14a3feSDimitry Andric operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { 256fe6060f1SDimitry Andric return __x.base() == __y.base(); 257fe6060f1SDimitry Andric } 258fe6060f1SDimitry Andric 25981ad6265SDimitry Andric #if _LIBCPP_STD_VER <= 17 260fe6060f1SDimitry Andric template <class _Iter1, class _Iter2> 261cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool 262cb14a3feSDimitry Andric operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { 263fe6060f1SDimitry Andric return __x.base() != __y.base(); 264fe6060f1SDimitry Andric } 26581ad6265SDimitry Andric #endif // _LIBCPP_STD_VER <= 17 266fe6060f1SDimitry Andric 267fe6060f1SDimitry Andric template <class _Iter1, class _Iter2> 268cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool 269cb14a3feSDimitry Andric operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { 27004eeddc0SDimitry Andric return __x.base() < __y.base(); 27104eeddc0SDimitry Andric } 27204eeddc0SDimitry Andric 27304eeddc0SDimitry Andric template <class _Iter1, class _Iter2> 274cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool 275cb14a3feSDimitry Andric operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { 276fe6060f1SDimitry Andric return __x.base() > __y.base(); 277fe6060f1SDimitry Andric } 278fe6060f1SDimitry Andric 279fe6060f1SDimitry Andric template <class _Iter1, class _Iter2> 280cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool 281cb14a3feSDimitry Andric operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { 282fe6060f1SDimitry Andric return __x.base() <= __y.base(); 283fe6060f1SDimitry Andric } 284fe6060f1SDimitry Andric 28504eeddc0SDimitry Andric template <class _Iter1, class _Iter2> 286cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool 287cb14a3feSDimitry Andric operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { 28804eeddc0SDimitry Andric return __x.base() >= __y.base(); 28904eeddc0SDimitry Andric } 29004eeddc0SDimitry Andric 29106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 29281ad6265SDimitry Andric template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> 293cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr auto 294*0fca6ea1SDimitry Andric operator<=>(const move_iterator<_Iter1>& __x, 295*0fca6ea1SDimitry Andric const move_iterator<_Iter2>& __y) -> compare_three_way_result_t<_Iter1, _Iter2> { 29681ad6265SDimitry Andric return __x.base() <=> __y.base(); 29781ad6265SDimitry Andric } 29806c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 29981ad6265SDimitry Andric 300fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 301fe6060f1SDimitry Andric template <class _Iter1, class _Iter2> 302cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto 303cb14a3feSDimitry Andric operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -> decltype(__x.base() - __y.base()) { 304fe6060f1SDimitry Andric return __x.base() - __y.base(); 305fe6060f1SDimitry Andric } 306fe6060f1SDimitry Andric #else 307fe6060f1SDimitry Andric template <class _Iter1, class _Iter2> 308cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type 309cb14a3feSDimitry Andric operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { 310fe6060f1SDimitry Andric return __x.base() - __y.base(); 311fe6060f1SDimitry Andric } 31281ad6265SDimitry Andric #endif // !_LIBCPP_CXX03_LANG 313fe6060f1SDimitry Andric 31406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 31581ad6265SDimitry Andric template <class _Iter> 316cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr move_iterator<_Iter> 317cb14a3feSDimitry Andric operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) 318cb14a3feSDimitry Andric requires requires { 319cb14a3feSDimitry Andric { __x.base() + __n } -> same_as<_Iter>; 320cb14a3feSDimitry Andric } 32181ad6265SDimitry Andric { 32281ad6265SDimitry Andric return __x + __n; 32381ad6265SDimitry Andric } 32481ad6265SDimitry Andric #else 325fe6060f1SDimitry Andric template <class _Iter> 326cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> 327cb14a3feSDimitry Andric operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { 328fe6060f1SDimitry Andric return move_iterator<_Iter>(__x.base() + __n); 329fe6060f1SDimitry Andric } 33006c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 331fe6060f1SDimitry Andric 332*0fca6ea1SDimitry Andric #if _LIBCPP_STD_VER >= 20 333*0fca6ea1SDimitry Andric template <class _Iter1, class _Iter2> 334*0fca6ea1SDimitry Andric requires(!sized_sentinel_for<_Iter1, _Iter2>) 335*0fca6ea1SDimitry Andric inline constexpr bool disable_sized_sentinel_for<move_iterator<_Iter1>, move_iterator<_Iter2>> = true; 336*0fca6ea1SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 337*0fca6ea1SDimitry Andric 338fe6060f1SDimitry Andric template <class _Iter> 339cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> make_move_iterator(_Iter __i) { 34081ad6265SDimitry Andric return move_iterator<_Iter>(std::move(__i)); 341fe6060f1SDimitry Andric } 342fe6060f1SDimitry Andric 343fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 344fe6060f1SDimitry Andric 34506c3fb27SDimitry Andric _LIBCPP_POP_MACROS 34606c3fb27SDimitry Andric 347fe6060f1SDimitry Andric #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H 348