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_REVERSE_ITERATOR_H 11 #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 12 13 #include <__compare/compare_three_way_result.h> 14 #include <__compare/three_way_comparable.h> 15 #include <__config> 16 #include <__iterator/iterator.h> 17 #include <__iterator/iterator_traits.h> 18 #include <__memory/addressof.h> 19 #include <type_traits> 20 21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22 #pragma GCC system_header 23 #endif 24 25 _LIBCPP_BEGIN_NAMESPACE_STD 26 27 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 28 template <class _Iter> 29 class _LIBCPP_TEMPLATE_VIS reverse_iterator 30 #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) 31 : public iterator<typename iterator_traits<_Iter>::iterator_category, 32 typename iterator_traits<_Iter>::value_type, 33 typename iterator_traits<_Iter>::difference_type, 34 typename iterator_traits<_Iter>::pointer, 35 typename iterator_traits<_Iter>::reference> 36 #endif 37 { 38 _LIBCPP_SUPPRESS_DEPRECATED_POP 39 private: 40 #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES 41 _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break 42 #endif 43 44 protected: 45 _Iter current; 46 public: 47 typedef _Iter iterator_type; 48 typedef typename iterator_traits<_Iter>::difference_type difference_type; 49 typedef typename iterator_traits<_Iter>::reference reference; 50 typedef typename iterator_traits<_Iter>::pointer pointer; 51 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, 52 random_access_iterator_tag, 53 typename iterator_traits<_Iter>::iterator_category> iterator_category; 54 typedef typename iterator_traits<_Iter>::value_type value_type; 55 56 #if _LIBCPP_STD_VER > 17 57 typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, 58 random_access_iterator_tag, 59 bidirectional_iterator_tag> iterator_concept; 60 #endif 61 62 #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES 63 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 64 reverse_iterator() : __t(), current() {} 65 66 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 67 explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} 68 69 template <class _Up, class = __enable_if_t< 70 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value 71 > > 72 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 73 reverse_iterator(const reverse_iterator<_Up>& __u) 74 : __t(__u.base()), current(__u.base()) 75 { } 76 77 template <class _Up, class = __enable_if_t< 78 !is_same<_Up, _Iter>::value && 79 is_convertible<_Up const&, _Iter>::value && 80 is_assignable<_Iter&, _Up const&>::value 81 > > 82 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 83 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { 84 __t = current = __u.base(); 85 return *this; 86 } 87 #else 88 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 89 reverse_iterator() : current() {} 90 91 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 92 explicit reverse_iterator(_Iter __x) : current(__x) {} 93 94 template <class _Up, class = __enable_if_t< 95 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value 96 > > 97 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 98 reverse_iterator(const reverse_iterator<_Up>& __u) 99 : current(__u.base()) 100 { } 101 102 template <class _Up, class = __enable_if_t< 103 !is_same<_Up, _Iter>::value && 104 is_convertible<_Up const&, _Iter>::value && 105 is_assignable<_Iter&, _Up const&>::value 106 > > 107 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 108 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { 109 current = __u.base(); 110 return *this; 111 } 112 #endif 113 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 114 _Iter base() const {return current;} 115 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 116 reference operator*() const {_Iter __tmp = current; return *--__tmp;} 117 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 118 pointer operator->() const {return _VSTD::addressof(operator*());} 119 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 120 reverse_iterator& operator++() {--current; return *this;} 121 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 122 reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} 123 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 124 reverse_iterator& operator--() {++current; return *this;} 125 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 126 reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} 127 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 128 reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);} 129 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 130 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} 131 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 132 reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);} 133 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 134 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} 135 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 136 reference operator[](difference_type __n) const {return *(*this + __n);} 137 }; 138 139 template <class _Iter1, class _Iter2> 140 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 141 bool 142 operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 143 { 144 return __x.base() == __y.base(); 145 } 146 147 template <class _Iter1, class _Iter2> 148 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 149 bool 150 operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 151 { 152 return __x.base() > __y.base(); 153 } 154 155 template <class _Iter1, class _Iter2> 156 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 157 bool 158 operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 159 { 160 return __x.base() != __y.base(); 161 } 162 163 template <class _Iter1, class _Iter2> 164 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 165 bool 166 operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 167 { 168 return __x.base() < __y.base(); 169 } 170 171 template <class _Iter1, class _Iter2> 172 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 173 bool 174 operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 175 { 176 return __x.base() <= __y.base(); 177 } 178 179 template <class _Iter1, class _Iter2> 180 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 181 bool 182 operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 183 { 184 return __x.base() >= __y.base(); 185 } 186 187 #if !defined(_LIBCPP_HAS_NO_CONCEPTS) 188 template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> 189 _LIBCPP_HIDE_FROM_ABI constexpr 190 compare_three_way_result_t<_Iter1, _Iter2> 191 operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 192 { 193 return __y.base() <=> __x.base(); 194 } 195 #endif 196 197 #ifndef _LIBCPP_CXX03_LANG 198 template <class _Iter1, class _Iter2> 199 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 200 auto 201 operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 202 -> decltype(__y.base() - __x.base()) 203 { 204 return __y.base() - __x.base(); 205 } 206 #else 207 template <class _Iter1, class _Iter2> 208 inline _LIBCPP_INLINE_VISIBILITY 209 typename reverse_iterator<_Iter1>::difference_type 210 operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 211 { 212 return __y.base() - __x.base(); 213 } 214 #endif 215 216 template <class _Iter> 217 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 218 reverse_iterator<_Iter> 219 operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) 220 { 221 return reverse_iterator<_Iter>(__x.base() - __n); 222 } 223 224 #if _LIBCPP_STD_VER > 11 225 template <class _Iter> 226 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 227 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) 228 { 229 return reverse_iterator<_Iter>(__i); 230 } 231 #endif 232 233 _LIBCPP_END_NAMESPACE_STD 234 235 #endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 236