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_WRAP_ITER_H 11 #define _LIBCPP___ITERATOR_WRAP_ITER_H 12 13 #include <__config> 14 #include <__debug> 15 #include <__iterator/iterator_traits.h> 16 #include <__memory/pointer_traits.h> // __to_address 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 _Iter> 26 class __wrap_iter 27 { 28 public: 29 typedef _Iter iterator_type; 30 typedef typename iterator_traits<iterator_type>::value_type value_type; 31 typedef typename iterator_traits<iterator_type>::difference_type difference_type; 32 typedef typename iterator_traits<iterator_type>::pointer pointer; 33 typedef typename iterator_traits<iterator_type>::reference reference; 34 typedef typename iterator_traits<iterator_type>::iterator_category iterator_category; 35 #if _LIBCPP_STD_VER > 17 36 typedef contiguous_iterator_tag iterator_concept; 37 #endif 38 39 private: 40 iterator_type __i; 41 public: 42 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT 43 #if _LIBCPP_STD_VER > 11 44 : __i{} 45 #endif 46 { 47 #if _LIBCPP_DEBUG_LEVEL == 2 48 __get_db()->__insert_i(this); 49 #endif 50 } 51 template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 52 __wrap_iter(const __wrap_iter<_Up>& __u, 53 typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT 54 : __i(__u.base()) 55 { 56 #if _LIBCPP_DEBUG_LEVEL == 2 57 __get_db()->__iterator_copy(this, &__u); 58 #endif 59 } 60 #if _LIBCPP_DEBUG_LEVEL == 2 61 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 62 __wrap_iter(const __wrap_iter& __x) 63 : __i(__x.base()) 64 { 65 __get_db()->__iterator_copy(this, &__x); 66 } 67 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 68 __wrap_iter& operator=(const __wrap_iter& __x) 69 { 70 if (this != &__x) 71 { 72 __get_db()->__iterator_copy(this, &__x); 73 __i = __x.__i; 74 } 75 return *this; 76 } 77 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 78 ~__wrap_iter() 79 { 80 __get_db()->__erase_i(this); 81 } 82 #endif 83 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT 84 { 85 #if _LIBCPP_DEBUG_LEVEL == 2 86 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 87 "Attempted to dereference a non-dereferenceable iterator"); 88 #endif 89 return *__i; 90 } 91 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT 92 { 93 #if _LIBCPP_DEBUG_LEVEL == 2 94 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 95 "Attempted to dereference a non-dereferenceable iterator"); 96 #endif 97 return _VSTD::__to_address(__i); 98 } 99 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT 100 { 101 #if _LIBCPP_DEBUG_LEVEL == 2 102 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 103 "Attempted to increment a non-incrementable iterator"); 104 #endif 105 ++__i; 106 return *this; 107 } 108 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT 109 {__wrap_iter __tmp(*this); ++(*this); return __tmp;} 110 111 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT 112 { 113 #if _LIBCPP_DEBUG_LEVEL == 2 114 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), 115 "Attempted to decrement a non-decrementable iterator"); 116 #endif 117 --__i; 118 return *this; 119 } 120 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT 121 {__wrap_iter __tmp(*this); --(*this); return __tmp;} 122 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT 123 {__wrap_iter __w(*this); __w += __n; return __w;} 124 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT 125 { 126 #if _LIBCPP_DEBUG_LEVEL == 2 127 _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), 128 "Attempted to add/subtract an iterator outside its valid range"); 129 #endif 130 __i += __n; 131 return *this; 132 } 133 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT 134 {return *this + (-__n);} 135 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT 136 {*this += -__n; return *this;} 137 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT 138 { 139 #if _LIBCPP_DEBUG_LEVEL == 2 140 _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), 141 "Attempted to subscript an iterator outside its valid range"); 142 #endif 143 return __i[__n]; 144 } 145 146 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;} 147 148 private: 149 #if _LIBCPP_DEBUG_LEVEL == 2 150 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x) 151 { 152 __get_db()->__insert_ic(this, __p); 153 } 154 #else 155 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} 156 #endif 157 158 template <class _Up> friend class __wrap_iter; 159 template <class _CharT, class _Traits, class _Alloc> friend class basic_string; 160 template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector; 161 template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span; 162 }; 163 164 template <class _Iter1> 165 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 166 bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 167 { 168 return __x.base() == __y.base(); 169 } 170 171 template <class _Iter1, class _Iter2> 172 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 173 bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 174 { 175 return __x.base() == __y.base(); 176 } 177 178 template <class _Iter1> 179 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 180 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 181 { 182 #if _LIBCPP_DEBUG_LEVEL == 2 183 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), 184 "Attempted to compare incomparable iterators"); 185 #endif 186 return __x.base() < __y.base(); 187 } 188 189 template <class _Iter1, class _Iter2> 190 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 191 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 192 { 193 #if _LIBCPP_DEBUG_LEVEL == 2 194 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), 195 "Attempted to compare incomparable iterators"); 196 #endif 197 return __x.base() < __y.base(); 198 } 199 200 template <class _Iter1> 201 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 202 bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 203 { 204 return !(__x == __y); 205 } 206 207 template <class _Iter1, class _Iter2> 208 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 209 bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 210 { 211 return !(__x == __y); 212 } 213 214 template <class _Iter1> 215 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 216 bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 217 { 218 return __y < __x; 219 } 220 221 template <class _Iter1, class _Iter2> 222 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 223 bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 224 { 225 return __y < __x; 226 } 227 228 template <class _Iter1> 229 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 230 bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 231 { 232 return !(__x < __y); 233 } 234 235 template <class _Iter1, class _Iter2> 236 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 237 bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 238 { 239 return !(__x < __y); 240 } 241 242 template <class _Iter1> 243 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 244 bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 245 { 246 return !(__y < __x); 247 } 248 249 template <class _Iter1, class _Iter2> 250 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 251 bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 252 { 253 return !(__y < __x); 254 } 255 256 template <class _Iter1, class _Iter2> 257 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 258 #ifndef _LIBCPP_CXX03_LANG 259 auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 260 -> decltype(__x.base() - __y.base()) 261 #else 262 typename __wrap_iter<_Iter1>::difference_type 263 operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 264 #endif // C++03 265 { 266 #if _LIBCPP_DEBUG_LEVEL == 2 267 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), 268 "Attempted to subtract incompatible iterators"); 269 #endif 270 return __x.base() - __y.base(); 271 } 272 273 template <class _Iter1> 274 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG 275 __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT 276 { 277 __x += __n; 278 return __x; 279 } 280 281 #if _LIBCPP_STD_VER <= 17 282 template <class _It> 283 struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {}; 284 #endif 285 286 template <class _Iter> 287 _LIBCPP_CONSTEXPR 288 decltype(_VSTD::__to_address(declval<_Iter>())) 289 __to_address(__wrap_iter<_Iter> __w) _NOEXCEPT { 290 return _VSTD::__to_address(__w.base()); 291 } 292 293 _LIBCPP_END_NAMESPACE_STD 294 295 #endif // _LIBCPP___ITERATOR_WRAP_ITER_H 296