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 public: 27 #if _LIBCPP_STD_VER > 17 28 typedef input_iterator_tag iterator_concept; 29 #endif 30 31 typedef _Iter iterator_type; 32 typedef _If< 33 __is_cpp17_random_access_iterator<_Iter>::value, 34 random_access_iterator_tag, 35 typename iterator_traits<_Iter>::iterator_category 36 > iterator_category; 37 typedef typename iterator_traits<iterator_type>::value_type value_type; 38 typedef typename iterator_traits<iterator_type>::difference_type difference_type; 39 typedef iterator_type pointer; 40 41 #ifndef _LIBCPP_CXX03_LANG 42 typedef typename iterator_traits<iterator_type>::reference __reference; 43 typedef typename conditional< 44 is_reference<__reference>::value, 45 typename remove_reference<__reference>::type&&, 46 __reference 47 >::type reference; 48 #else 49 typedef typename iterator_traits<iterator_type>::reference reference; 50 #endif 51 52 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 53 move_iterator() : __current_() {} 54 55 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 56 explicit move_iterator(_Iter __i) : __current_(__i) {} 57 58 template <class _Up, class = __enable_if_t< 59 !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value 60 > > 61 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 62 move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} 63 64 template <class _Up, class = __enable_if_t< 65 !is_same<_Up, _Iter>::value && 66 is_convertible<const _Up&, _Iter>::value && 67 is_assignable<_Iter&, const _Up&>::value 68 > > 69 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 70 move_iterator& operator=(const move_iterator<_Up>& __u) { 71 __current_ = __u.base(); 72 return *this; 73 } 74 75 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 76 _Iter base() const { return __current_; } 77 78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 79 reference operator*() const { return static_cast<reference>(*__current_); } 80 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 81 pointer operator->() const { return __current_; } 82 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 83 reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); } 84 85 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 86 move_iterator& operator++() { ++__current_; return *this; } 87 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 88 move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } 89 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 90 move_iterator& operator--() { --__current_; return *this; } 91 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 92 move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } 93 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 94 move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } 95 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 96 move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } 97 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 98 move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } 99 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 100 move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } 101 102 private: 103 _Iter __current_; 104 }; 105 106 template <class _Iter1, class _Iter2> 107 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 108 bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 109 { 110 return __x.base() == __y.base(); 111 } 112 113 template <class _Iter1, class _Iter2> 114 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 115 bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 116 { 117 return __x.base() != __y.base(); 118 } 119 120 template <class _Iter1, class _Iter2> 121 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 122 bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 123 { 124 return __x.base() < __y.base(); 125 } 126 127 template <class _Iter1, class _Iter2> 128 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 129 bool 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_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 136 bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 137 { 138 return __x.base() <= __y.base(); 139 } 140 141 template <class _Iter1, class _Iter2> 142 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 143 bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) 144 { 145 return __x.base() >= __y.base(); 146 } 147 148 #ifndef _LIBCPP_CXX03_LANG 149 template <class _Iter1, class _Iter2> 150 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 151 auto 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI _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_HIDE_FROM_ABI _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