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