xref: /llvm-project/libcxx/include/__iterator/move_iterator.h (revision 4814628531451efb91ab0f4ab047f3a0469aef82)
1f32f3db9SLouis Dionne // -*- C++ -*-
2f32f3db9SLouis Dionne //===----------------------------------------------------------------------===//
3f32f3db9SLouis Dionne //
4f32f3db9SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5f32f3db9SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
6f32f3db9SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7f32f3db9SLouis Dionne //
8f32f3db9SLouis Dionne //===----------------------------------------------------------------------===//
9f32f3db9SLouis Dionne 
10f32f3db9SLouis Dionne #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H
11f32f3db9SLouis Dionne #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H
12f32f3db9SLouis Dionne 
132fb026eeSArthur O'Dwyer #include <__compare/compare_three_way_result.h>
142fb026eeSArthur O'Dwyer #include <__compare/three_way_comparable.h>
152fb026eeSArthur O'Dwyer #include <__concepts/assignable.h>
162fb026eeSArthur O'Dwyer #include <__concepts/convertible_to.h>
172fb026eeSArthur O'Dwyer #include <__concepts/derived_from.h>
182fb026eeSArthur O'Dwyer #include <__concepts/same_as.h>
19f32f3db9SLouis Dionne #include <__config>
202fb026eeSArthur O'Dwyer #include <__iterator/concepts.h>
212fb026eeSArthur O'Dwyer #include <__iterator/incrementable_traits.h>
222fb026eeSArthur O'Dwyer #include <__iterator/iter_move.h>
232fb026eeSArthur O'Dwyer #include <__iterator/iter_swap.h>
24f32f3db9SLouis Dionne #include <__iterator/iterator_traits.h>
252fb026eeSArthur O'Dwyer #include <__iterator/move_sentinel.h>
262fb026eeSArthur O'Dwyer #include <__iterator/readable_traits.h>
27430b397fSNikolas Klauser #include <__type_traits/conditional.h>
28e7ceb4adSLouis Dionne #include <__type_traits/enable_if.h>
29430b397fSNikolas Klauser #include <__type_traits/is_assignable.h>
30430b397fSNikolas Klauser #include <__type_traits/is_constructible.h>
3148e862d0SMichael Buch #include <__type_traits/is_convertible.h>
32e7ceb4adSLouis Dionne #include <__type_traits/is_reference.h>
33430b397fSNikolas Klauser #include <__type_traits/is_same.h>
3448e862d0SMichael Buch #include <__type_traits/remove_reference.h>
35430b397fSNikolas Klauser #include <__utility/declval.h>
367ea4fe7eSArthur O'Dwyer #include <__utility/move.h>
37f32f3db9SLouis Dionne 
38f32f3db9SLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
39f32f3db9SLouis Dionne #  pragma GCC system_header
40f32f3db9SLouis Dionne #endif
41f32f3db9SLouis Dionne 
4292e4d679SNicole Rabjohn _LIBCPP_PUSH_MACROS
4392e4d679SNicole Rabjohn #include <__undef_macros>
4492e4d679SNicole Rabjohn 
45f32f3db9SLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
46f32f3db9SLouis Dionne 
474f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
482fb026eeSArthur O'Dwyer template <class _Iter, class = void>
492fb026eeSArthur O'Dwyer struct __move_iter_category_base {};
502fb026eeSArthur O'Dwyer 
512fb026eeSArthur O'Dwyer template <class _Iter>
522fb026eeSArthur O'Dwyer   requires requires { typename iterator_traits<_Iter>::iterator_category; }
532fb026eeSArthur O'Dwyer struct __move_iter_category_base<_Iter> {
549783f28cSLouis Dionne   using iterator_category =
559783f28cSLouis Dionne       _If< derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>,
562fb026eeSArthur O'Dwyer            random_access_iterator_tag,
579783f28cSLouis Dionne            typename iterator_traits<_Iter>::iterator_category >;
582fb026eeSArthur O'Dwyer };
592fb026eeSArthur O'Dwyer 
602fb026eeSArthur O'Dwyer template <class _Iter, class _Sent>
612fb026eeSArthur O'Dwyer concept __move_iter_comparable = requires {
6273e8e1baSNikolas Klauser   { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>;
632fb026eeSArthur O'Dwyer };
644f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
652fb026eeSArthur O'Dwyer 
66f32f3db9SLouis Dionne template <class _Iter>
67f32f3db9SLouis Dionne class _LIBCPP_TEMPLATE_VIS move_iterator
684f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
692fb026eeSArthur O'Dwyer     : public __move_iter_category_base<_Iter>
702fb026eeSArthur O'Dwyer #endif
71f32f3db9SLouis Dionne {
72813e1da9SShivam kunwar #if _LIBCPP_STD_VER >= 20
739783f28cSLouis Dionne 
74813e1da9SShivam kunwar private:
759783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static constexpr auto __get_iter_concept() {
76813e1da9SShivam kunwar     if constexpr (random_access_iterator<_Iter>) {
77813e1da9SShivam kunwar       return random_access_iterator_tag{};
78813e1da9SShivam kunwar     } else if constexpr (bidirectional_iterator<_Iter>) {
79813e1da9SShivam kunwar       return bidirectional_iterator_tag{};
80813e1da9SShivam kunwar     } else if constexpr (forward_iterator<_Iter>) {
81813e1da9SShivam kunwar       return forward_iterator_tag{};
82813e1da9SShivam kunwar     } else {
83813e1da9SShivam kunwar       return input_iterator_tag{};
84813e1da9SShivam kunwar     }
85813e1da9SShivam kunwar   }
86813e1da9SShivam kunwar #endif // _LIBCPP_STD_VER >= 20
879783f28cSLouis Dionne 
88f32f3db9SLouis Dionne public:
894f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
902fb026eeSArthur O'Dwyer   using iterator_type    = _Iter;
91813e1da9SShivam kunwar   using iterator_concept = decltype(__get_iter_concept());
922fb026eeSArthur O'Dwyer   // iterator_category is inherited and not always present
932fb026eeSArthur O'Dwyer   using value_type      = iter_value_t<_Iter>;
942fb026eeSArthur O'Dwyer   using difference_type = iter_difference_t<_Iter>;
952fb026eeSArthur O'Dwyer   using pointer         = _Iter;
962fb026eeSArthur O'Dwyer   using reference       = iter_rvalue_reference_t<_Iter>;
972fb026eeSArthur O'Dwyer #else
980ab54c28SArthur O'Dwyer   typedef _Iter iterator_type;
999783f28cSLouis Dionne   typedef _If< __has_random_access_iterator_category<_Iter>::value,
1000ab54c28SArthur O'Dwyer                random_access_iterator_tag,
1019783f28cSLouis Dionne                typename iterator_traits<_Iter>::iterator_category >
1029783f28cSLouis Dionne       iterator_category;
1030ab54c28SArthur O'Dwyer   typedef typename iterator_traits<iterator_type>::value_type value_type;
1040ab54c28SArthur O'Dwyer   typedef typename iterator_traits<iterator_type>::difference_type difference_type;
1050ab54c28SArthur O'Dwyer   typedef iterator_type pointer;
1060ab54c28SArthur O'Dwyer 
107f32f3db9SLouis Dionne   typedef typename iterator_traits<iterator_type>::reference __reference;
108*48146285SNikolas Klauser   typedef __conditional_t<is_reference<__reference>::value, __libcpp_remove_reference_t<__reference>&&, __reference>
109*48146285SNikolas Klauser       reference;
1104f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
1112fb026eeSArthur O'Dwyer 
1129783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {}
1132fb026eeSArthur O'Dwyer 
1149783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator++() {
1159783f28cSLouis Dionne     ++__current_;
1169783f28cSLouis Dionne     return *this;
1179783f28cSLouis Dionne   }
118b06049bcSKonstantin Varlamov 
1199783f28cSLouis Dionne   _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const {
1209783f28cSLouis Dionne     return __current_;
1219783f28cSLouis Dionne   }
12279a2b4baSKonstantin Varlamov 
1234f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
1249783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr move_iterator()
1259783f28cSLouis Dionne     requires is_constructible_v<_Iter>
1269783f28cSLouis Dionne       : __current_() {}
1272fb026eeSArthur O'Dwyer 
1282fb026eeSArthur O'Dwyer   template <class _Up>
1292fb026eeSArthur O'Dwyer     requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter>
1309783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {}
1312fb026eeSArthur O'Dwyer 
1322fb026eeSArthur O'Dwyer   template <class _Up>
1339783f28cSLouis Dionne     requires(!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> && assignable_from<_Iter&, const _Up&>
1349783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr move_iterator& operator=(const move_iterator<_Up>& __u) {
1352fb026eeSArthur O'Dwyer     __current_ = __u.base();
1362fb026eeSArthur O'Dwyer     return *this;
1372fb026eeSArthur O'Dwyer   }
1382fb026eeSArthur O'Dwyer 
1392fb026eeSArthur O'Dwyer   _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; }
1402fb026eeSArthur O'Dwyer   _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); }
1412fb026eeSArthur O'Dwyer 
1429783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return ranges::iter_move(__current_); }
1439783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const {
1449783f28cSLouis Dionne     return ranges::iter_move(__current_ + __n);
1452fb026eeSArthur O'Dwyer   }
1462fb026eeSArthur O'Dwyer 
1479783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr auto operator++(int)
1489783f28cSLouis Dionne     requires forward_iterator<_Iter>
1499783f28cSLouis Dionne   {
1509783f28cSLouis Dionne     move_iterator __tmp(*this);
1519783f28cSLouis Dionne     ++__current_;
1529783f28cSLouis Dionne     return __tmp;
1539783f28cSLouis Dionne   }
1549783f28cSLouis Dionne 
1559783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }
1562fb026eeSArthur O'Dwyer #else
1579783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator() : __current_() {}
158f32f3db9SLouis Dionne 
15976a24727SNikolas Klauser   template <class _Up, __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value, int> = 0>
1609783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator(const move_iterator<_Up>& __u)
1619783f28cSLouis Dionne       : __current_(__u.base()) {}
162f32f3db9SLouis Dionne 
1639783f28cSLouis Dionne   template <class _Up,
16476a24727SNikolas Klauser             __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value &&
16576a24727SNikolas Klauser                                is_assignable<_Iter&, const _Up&>::value,
16676a24727SNikolas Klauser                            int> = 0>
1679783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator=(const move_iterator<_Up>& __u) {
1689542c9c5SArthur O'Dwyer     __current_ = __u.base();
169f32f3db9SLouis Dionne     return *this;
170f32f3db9SLouis Dionne   }
171f32f3db9SLouis Dionne 
1729783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return __current_; }
1730ab54c28SArthur O'Dwyer 
1749783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const {
1759783f28cSLouis Dionne     return static_cast<reference>(*__current_);
1769783f28cSLouis Dionne   }
1779783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const {
1789783f28cSLouis Dionne     return static_cast<reference>(__current_[__n]);
1799783f28cSLouis Dionne   }
1800ab54c28SArthur O'Dwyer 
1819783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator++(int) {
1829783f28cSLouis Dionne     move_iterator __tmp(*this);
1839783f28cSLouis Dionne     ++__current_;
1849783f28cSLouis Dionne     return __tmp;
1859783f28cSLouis Dionne   }
1864f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
1872fb026eeSArthur O'Dwyer 
1889783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator--() {
1899783f28cSLouis Dionne     --__current_;
1909783f28cSLouis Dionne     return *this;
1919783f28cSLouis Dionne   }
1929783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator--(int) {
1939783f28cSLouis Dionne     move_iterator __tmp(*this);
1949783f28cSLouis Dionne     --__current_;
1959783f28cSLouis Dionne     return __tmp;
1969783f28cSLouis Dionne   }
1979783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator+(difference_type __n) const {
1989783f28cSLouis Dionne     return move_iterator(__current_ + __n);
1999783f28cSLouis Dionne   }
2009783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator+=(difference_type __n) {
2019783f28cSLouis Dionne     __current_ += __n;
2029783f28cSLouis Dionne     return *this;
2039783f28cSLouis Dionne   }
2049783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator-(difference_type __n) const {
2059783f28cSLouis Dionne     return move_iterator(__current_ - __n);
2069783f28cSLouis Dionne   }
2079783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator-=(difference_type __n) {
2089783f28cSLouis Dionne     __current_ -= __n;
2099783f28cSLouis Dionne     return *this;
2109783f28cSLouis Dionne   }
2119542c9c5SArthur O'Dwyer 
2124f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
2132fb026eeSArthur O'Dwyer   template <sentinel_for<_Iter> _Sent>
2149783f28cSLouis Dionne   friend _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
2152fb026eeSArthur O'Dwyer     requires __move_iter_comparable<_Iter, _Sent>
2162fb026eeSArthur O'Dwyer   {
2172fb026eeSArthur O'Dwyer     return __x.base() == __y.base();
2182fb026eeSArthur O'Dwyer   }
2192fb026eeSArthur O'Dwyer 
2202fb026eeSArthur O'Dwyer   template <sized_sentinel_for<_Iter> _Sent>
2219783f28cSLouis Dionne   friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
2229783f28cSLouis Dionne   operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) {
2232fb026eeSArthur O'Dwyer     return __x.base() - __y.base();
2242fb026eeSArthur O'Dwyer   }
2252fb026eeSArthur O'Dwyer 
2262fb026eeSArthur O'Dwyer   template <sized_sentinel_for<_Iter> _Sent>
2279783f28cSLouis Dionne   friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
2289783f28cSLouis Dionne   operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) {
2292fb026eeSArthur O'Dwyer     return __x.base() - __y.base();
2302fb026eeSArthur O'Dwyer   }
2312fb026eeSArthur O'Dwyer 
2329783f28cSLouis Dionne   friend _LIBCPP_HIDE_FROM_ABI constexpr iter_rvalue_reference_t<_Iter>
2339783f28cSLouis Dionne   iter_move(const move_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) {
2342fb026eeSArthur O'Dwyer     return ranges::iter_move(__i.__current_);
2352fb026eeSArthur O'Dwyer   }
2362fb026eeSArthur O'Dwyer 
2372fb026eeSArthur O'Dwyer   template <indirectly_swappable<_Iter> _It2>
2389783f28cSLouis Dionne   friend _LIBCPP_HIDE_FROM_ABI constexpr void
2399783f28cSLouis Dionne   iter_swap(const move_iterator& __x,
2409783f28cSLouis Dionne             const move_iterator<_It2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) {
2412fb026eeSArthur O'Dwyer     return ranges::iter_swap(__x.__current_, __y.__current_);
2422fb026eeSArthur O'Dwyer   }
2434f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
2442fb026eeSArthur O'Dwyer 
2459542c9c5SArthur O'Dwyer private:
2469783f28cSLouis Dionne   template <class _It2>
2479783f28cSLouis Dionne   friend class move_iterator;
2482fb026eeSArthur O'Dwyer 
2499542c9c5SArthur O'Dwyer   _Iter __current_;
250f32f3db9SLouis Dionne };
251c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator);
252f32f3db9SLouis Dionne 
253f32f3db9SLouis Dionne template <class _Iter1, class _Iter2>
2549783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
2559783f28cSLouis Dionne operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
256f32f3db9SLouis Dionne   return __x.base() == __y.base();
257f32f3db9SLouis Dionne }
258f32f3db9SLouis Dionne 
2592fb026eeSArthur O'Dwyer #if _LIBCPP_STD_VER <= 17
260f32f3db9SLouis Dionne template <class _Iter1, class _Iter2>
2619783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
2629783f28cSLouis Dionne operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
263f32f3db9SLouis Dionne   return __x.base() != __y.base();
264f32f3db9SLouis Dionne }
2652fb026eeSArthur O'Dwyer #endif // _LIBCPP_STD_VER <= 17
266f32f3db9SLouis Dionne 
267f32f3db9SLouis Dionne template <class _Iter1, class _Iter2>
2689783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
2699783f28cSLouis Dionne operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
2700ab54c28SArthur O'Dwyer   return __x.base() < __y.base();
2710ab54c28SArthur O'Dwyer }
2720ab54c28SArthur O'Dwyer 
2730ab54c28SArthur O'Dwyer template <class _Iter1, class _Iter2>
2749783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
2759783f28cSLouis Dionne operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
276f32f3db9SLouis Dionne   return __x.base() > __y.base();
277f32f3db9SLouis Dionne }
278f32f3db9SLouis Dionne 
279f32f3db9SLouis Dionne template <class _Iter1, class _Iter2>
2809783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
2819783f28cSLouis Dionne operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
2820ab54c28SArthur O'Dwyer   return __x.base() <= __y.base();
283f32f3db9SLouis Dionne }
284f32f3db9SLouis Dionne 
285f32f3db9SLouis Dionne template <class _Iter1, class _Iter2>
2869783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool
2879783f28cSLouis Dionne operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
2880ab54c28SArthur O'Dwyer   return __x.base() >= __y.base();
289f32f3db9SLouis Dionne }
290f32f3db9SLouis Dionne 
2914f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
2922fb026eeSArthur O'Dwyer template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
2939783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI constexpr auto
294e2c2ffbeSLouis Dionne operator<=>(const move_iterator<_Iter1>& __x,
295e2c2ffbeSLouis Dionne             const move_iterator<_Iter2>& __y) -> compare_three_way_result_t<_Iter1, _Iter2> {
2962fb026eeSArthur O'Dwyer   return __x.base() <=> __y.base();
2972fb026eeSArthur O'Dwyer }
2984f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
2992fb026eeSArthur O'Dwyer 
300f32f3db9SLouis Dionne #ifndef _LIBCPP_CXX03_LANG
301f32f3db9SLouis Dionne template <class _Iter1, class _Iter2>
3029783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto
3039783f28cSLouis Dionne operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -> decltype(__x.base() - __y.base()) {
304f32f3db9SLouis Dionne   return __x.base() - __y.base();
305f32f3db9SLouis Dionne }
306f32f3db9SLouis Dionne #else
307f32f3db9SLouis Dionne template <class _Iter1, class _Iter2>
3089783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type
3099783f28cSLouis Dionne operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) {
310f32f3db9SLouis Dionne   return __x.base() - __y.base();
311f32f3db9SLouis Dionne }
312db6421ecSLouis Dionne #endif // !_LIBCPP_CXX03_LANG
313f32f3db9SLouis Dionne 
3144f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
3152fb026eeSArthur O'Dwyer template <class _Iter>
3169783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI constexpr move_iterator<_Iter>
3179783f28cSLouis Dionne operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
3189783f28cSLouis Dionne   requires requires {
3199783f28cSLouis Dionne     { __x.base() + __n } -> same_as<_Iter>;
3209783f28cSLouis Dionne   }
3212fb026eeSArthur O'Dwyer {
3222fb026eeSArthur O'Dwyer   return __x + __n;
3232fb026eeSArthur O'Dwyer }
3242fb026eeSArthur O'Dwyer #else
325f32f3db9SLouis Dionne template <class _Iter>
3269783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter>
3279783f28cSLouis Dionne operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) {
328f32f3db9SLouis Dionne   return move_iterator<_Iter>(__x.base() + __n);
329f32f3db9SLouis Dionne }
3304f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
331f32f3db9SLouis Dionne 
332f4e3226aSXiaoyang Liu #if _LIBCPP_STD_VER >= 20
333f4e3226aSXiaoyang Liu template <class _Iter1, class _Iter2>
334f4e3226aSXiaoyang Liu   requires(!sized_sentinel_for<_Iter1, _Iter2>)
335f4e3226aSXiaoyang Liu inline constexpr bool disable_sized_sentinel_for<move_iterator<_Iter1>, move_iterator<_Iter2>> = true;
336f4e3226aSXiaoyang Liu #endif // _LIBCPP_STD_VER >= 20
337f4e3226aSXiaoyang Liu 
338f32f3db9SLouis Dionne template <class _Iter>
3399783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> make_move_iterator(_Iter __i) {
3402fb026eeSArthur O'Dwyer   return move_iterator<_Iter>(std::move(__i));
341f32f3db9SLouis Dionne }
342f32f3db9SLouis Dionne 
343f32f3db9SLouis Dionne _LIBCPP_END_NAMESPACE_STD
344f32f3db9SLouis Dionne 
34592e4d679SNicole Rabjohn _LIBCPP_POP_MACROS
34692e4d679SNicole Rabjohn 
347f32f3db9SLouis Dionne #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H
348