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