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 27template <class _Iter> 28class __wrap_iter 29{ 30public: 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 41private: 42 iterator_type __i_; 43public: 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 138private: 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 155template <class _Iter1> 156_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 157bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 158{ 159 return __x.base() == __y.base(); 160} 161 162template <class _Iter1, class _Iter2> 163_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 164bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 165{ 166 return __x.base() == __y.base(); 167} 168 169template <class _Iter1> 170_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 171bool 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 178template <class _Iter1, class _Iter2> 179_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 180bool 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 187template <class _Iter1> 188_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 189bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 190{ 191 return !(__x == __y); 192} 193 194template <class _Iter1, class _Iter2> 195_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 196bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 197{ 198 return !(__x == __y); 199} 200 201template <class _Iter1> 202_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 203bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 204{ 205 return __y < __x; 206} 207 208template <class _Iter1, class _Iter2> 209_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 210bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 211{ 212 return __y < __x; 213} 214 215template <class _Iter1> 216_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 217bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 218{ 219 return !(__x < __y); 220} 221 222template <class _Iter1, class _Iter2> 223_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 224bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 225{ 226 return !(__x < __y); 227} 228 229template <class _Iter1> 230_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 231bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT 232{ 233 return !(__y < __x); 234} 235 236template <class _Iter1, class _Iter2> 237_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 238bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 239{ 240 return !(__y < __x); 241} 242 243template <class _Iter1, class _Iter2> 244_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 245#ifndef _LIBCPP_CXX03_LANG 246auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 247 -> decltype(__x.base() - __y.base()) 248#else 249typename __wrap_iter<_Iter1>::difference_type 250operator-(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 258template <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 267template <class _It> 268struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {}; 269#endif 270 271template <class _It> 272struct _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