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 __wrap_iter(const void* __p, iterator_type __x) : __i(__x) 140 { 141 if (!__libcpp_is_constant_evaluated()) 142 __get_db()->__insert_ic(this, __p); 143 } 144 #else 145 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} 146 #endif 147 148 template <class _Up> friend class __wrap_iter; 149 template <class _CharT, class _Traits, class _Alloc> friend class basic_string; 150 template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector; 151 template <class _Tp, size_t> friend class _LIBCPP_TEMPLATE_VIS span; 152 }; 153 154 template <class _Iter1> 155 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 156 bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 157 { 158 return __x.base() == __y.base(); 159 } 160 161 template <class _Iter1, class _Iter2> 162 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 163 bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 164 { 165 return __x.base() == __y.base(); 166 } 167 168 template <class _Iter1> 169 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 170 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 171 { 172 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), 173 "Attempted to compare incomparable iterators"); 174 return __x.base() < __y.base(); 175 } 176 177 template <class _Iter1, class _Iter2> 178 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 179 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 180 { 181 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), 182 "Attempted to compare incomparable iterators"); 183 return __x.base() < __y.base(); 184 } 185 186 template <class _Iter1> 187 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 188 bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 189 { 190 return !(__x == __y); 191 } 192 193 template <class _Iter1, class _Iter2> 194 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 195 bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 196 { 197 return !(__x == __y); 198 } 199 200 template <class _Iter1> 201 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 202 bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 203 { 204 return __y < __x; 205 } 206 207 template <class _Iter1, class _Iter2> 208 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 209 bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 210 { 211 return __y < __x; 212 } 213 214 template <class _Iter1> 215 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 216 bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 217 { 218 return !(__x < __y); 219 } 220 221 template <class _Iter1, class _Iter2> 222 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 223 bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 224 { 225 return !(__x < __y); 226 } 227 228 template <class _Iter1> 229 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 230 bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 231 { 232 return !(__y < __x); 233 } 234 235 template <class _Iter1, class _Iter2> 236 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 237 bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 238 { 239 return !(__y < __x); 240 } 241 242 template <class _Iter1, class _Iter2> 243 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 244 #ifndef _LIBCPP_CXX03_LANG 245 auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 246 -> decltype(__x.base() - __y.base()) 247 #else 248 typename __wrap_iter<_Iter1>::difference_type 249 operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 250 #endif // C++03 251 { 252 _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), 253 "Attempted to subtract incompatible iterators"); 254 return __x.base() - __y.base(); 255 } 256 257 template <class _Iter1> 258 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 259 __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT 260 { 261 __x += __n; 262 return __x; 263 } 264 265 #if _LIBCPP_STD_VER <= 17 266 template <class _It> 267 struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {}; 268 #endif 269 270 template <class _It> 271 struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> > 272 { 273 typedef __wrap_iter<_It> pointer; 274 typedef typename pointer_traits<_It>::element_type element_type; 275 typedef typename pointer_traits<_It>::difference_type difference_type; 276 277 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 278 static element_type *to_address(pointer __w) _NOEXCEPT { 279 return _VSTD::__to_address(__w.base()); 280 } 281 }; 282 283 _LIBCPP_END_NAMESPACE_STD 284 285 #endif // _LIBCPP___ITERATOR_WRAP_ITER_H 286