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