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