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