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 <__config> 14 #include <__iterator/iterator_traits.h> 15 #include <type_traits> 16 17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18 #pragma GCC system_header 19 #endif 20 21 _LIBCPP_BEGIN_NAMESPACE_STD 22 23 template <class _Iter> 24 class _LIBCPP_TEMPLATE_VIS move_iterator 25 { 26 private: 27 _Iter __i; 28 public: 29 typedef _Iter iterator_type; 30 typedef typename iterator_traits<iterator_type>::value_type value_type; 31 typedef typename iterator_traits<iterator_type>::difference_type difference_type; 32 typedef iterator_type pointer; 33 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, 34 random_access_iterator_tag, 35 typename iterator_traits<_Iter>::iterator_category> iterator_category; 36 #if _LIBCPP_STD_VER > 17 37 typedef input_iterator_tag iterator_concept; 38 #endif 39 40 #ifndef _LIBCPP_CXX03_LANG 41 typedef typename iterator_traits<iterator_type>::reference __reference; 42 typedef typename conditional< 43 is_reference<__reference>::value, 44 typename remove_reference<__reference>::type&&, 45 __reference 46 >::type reference; 47 #else 48 typedef typename iterator_traits<iterator_type>::reference reference; 49 #endif 50 51 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 52 move_iterator() : __i() {} 53 54 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 55 explicit move_iterator(_Iter __x) : __i(__x) {} 56 57 template <class _Up, class = __enable_if_t< 58 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value 59 > > 60 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 61 move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {} 62 63 template <class _Up, class = __enable_if_t< 64 !is_same<_Up, _Iter>::value && 65 is_convertible<_Up const&, _Iter>::value && 66 is_assignable<_Iter&, _Up const&>::value 67 > > 68 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 69 move_iterator& operator=(const move_iterator<_Up>& __u) { 70 __i = __u.base(); 71 return *this; 72 } 73 74 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;} 75 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 76 reference operator*() const { return static_cast<reference>(*__i); } 77 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 78 pointer operator->() const { return __i;} 79 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 80 move_iterator& operator++() {++__i; return *this;} 81 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 82 move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;} 83 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 84 move_iterator& operator--() {--__i; return *this;} 85 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 86 move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;} 87 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 88 move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);} 89 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 90 move_iterator& operator+=(difference_type __n) {__i += __n; return *this;} 91 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 92 move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);} 93 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 94 move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;} 95 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 96 reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); } 97 }; 98 99 template <class _Iter1, class _Iter2> 100 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 101 bool 102 operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 103 { 104 return __x.base() == __y.base(); 105 } 106 107 template <class _Iter1, class _Iter2> 108 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 109 bool 110 operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 111 { 112 return __x.base() < __y.base(); 113 } 114 115 template <class _Iter1, class _Iter2> 116 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 117 bool 118 operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 119 { 120 return __x.base() != __y.base(); 121 } 122 123 template <class _Iter1, class _Iter2> 124 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 125 bool 126 operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 127 { 128 return __x.base() > __y.base(); 129 } 130 131 template <class _Iter1, class _Iter2> 132 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 133 bool 134 operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 135 { 136 return __x.base() >= __y.base(); 137 } 138 139 template <class _Iter1, class _Iter2> 140 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 141 bool 142 operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 143 { 144 return __x.base() <= __y.base(); 145 } 146 147 #ifndef _LIBCPP_CXX03_LANG 148 template <class _Iter1, class _Iter2> 149 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 150 auto 151 operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 152 -> decltype(__x.base() - __y.base()) 153 { 154 return __x.base() - __y.base(); 155 } 156 #else 157 template <class _Iter1, class _Iter2> 158 inline _LIBCPP_INLINE_VISIBILITY 159 typename move_iterator<_Iter1>::difference_type 160 operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 161 { 162 return __x.base() - __y.base(); 163 } 164 #endif 165 166 template <class _Iter> 167 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 168 move_iterator<_Iter> 169 operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) 170 { 171 return move_iterator<_Iter>(__x.base() + __n); 172 } 173 174 template <class _Iter> 175 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 176 move_iterator<_Iter> 177 make_move_iterator(_Iter __i) 178 { 179 return move_iterator<_Iter>(__i); 180 } 181 182 _LIBCPP_END_NAMESPACE_STD 183 184 #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H 185