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