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