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 <__compare/ordering.h> 14 #include <__compare/three_way_comparable.h> 15 #include <__config> 16 #include <__iterator/iterator_traits.h> 17 #include <__memory/addressof.h> 18 #include <__memory/pointer_traits.h> 19 #include <__type_traits/enable_if.h> 20 #include <__type_traits/is_convertible.h> 21 #include <cstddef> 22 23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 24 # pragma GCC system_header 25 #endif 26 27 _LIBCPP_BEGIN_NAMESPACE_STD 28 29 template <class _Iter> 30 class __wrap_iter { 31 public: 32 typedef _Iter iterator_type; 33 typedef typename iterator_traits<iterator_type>::value_type value_type; 34 typedef typename iterator_traits<iterator_type>::difference_type difference_type; 35 typedef typename iterator_traits<iterator_type>::pointer pointer; 36 typedef typename iterator_traits<iterator_type>::reference reference; 37 typedef typename iterator_traits<iterator_type>::iterator_category iterator_category; 38 #if _LIBCPP_STD_VER >= 20 39 typedef contiguous_iterator_tag iterator_concept; 40 #endif 41 42 private: 43 iterator_type __i_; 44 45 public: __wrap_iter()46 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT : __i_() {} 47 template <class _Up, __enable_if_t<is_convertible<_Up, iterator_type>::value, int> = 0> __wrap_iter(const __wrap_iter<_Up> & __u)48 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter(const __wrap_iter<_Up>& __u) _NOEXCEPT 49 : __i_(__u.base()) {} 50 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { return *__i_; } 51 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { 52 return std::__to_address(__i_); 53 } 54 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT { 55 ++__i_; 56 return *this; 57 } 58 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator++(int) _NOEXCEPT { 59 __wrap_iter __tmp(*this); 60 ++(*this); 61 return __tmp; 62 } 63 64 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT { 65 --__i_; 66 return *this; 67 } 68 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator--(int) _NOEXCEPT { 69 __wrap_iter __tmp(*this); 70 --(*this); 71 return __tmp; 72 } 73 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator+(difference_type __n) const _NOEXCEPT { 74 __wrap_iter __w(*this); 75 __w += __n; 76 return __w; 77 } 78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT { 79 __i_ += __n; 80 return *this; 81 } 82 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator-(difference_type __n) const _NOEXCEPT { 83 return *this + (-__n); 84 } 85 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT { 86 *this += -__n; 87 return *this; 88 } 89 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { 90 return __i_[__n]; 91 } 92 base()93 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator_type base() const _NOEXCEPT { return __i_; } 94 95 private: __wrap_iter(iterator_type __x)96 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __wrap_iter(iterator_type __x) _NOEXCEPT : __i_(__x) {} 97 98 template <class _Up> 99 friend class __wrap_iter; 100 template <class _CharT, class _Traits, class _Alloc> 101 friend class basic_string; 102 template <class _CharT, class _Traits> 103 friend class basic_string_view; 104 template <class _Tp, class _Alloc> 105 friend class _LIBCPP_TEMPLATE_VIS vector; 106 template <class _Tp, size_t> 107 friend class _LIBCPP_TEMPLATE_VIS span; 108 template <class _Tp, size_t _Size> 109 friend struct array; 110 }; 111 112 template <class _Iter1> 113 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 114 operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 115 return __x.base() == __y.base(); 116 } 117 118 template <class _Iter1, class _Iter2> 119 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 120 operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 121 return __x.base() == __y.base(); 122 } 123 124 template <class _Iter1> 125 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 126 operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 127 return __x.base() < __y.base(); 128 } 129 130 template <class _Iter1, class _Iter2> 131 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 132 operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 133 return __x.base() < __y.base(); 134 } 135 136 #if _LIBCPP_STD_VER <= 17 137 template <class _Iter1> 138 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 139 operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 140 return !(__x == __y); 141 } 142 143 template <class _Iter1, class _Iter2> 144 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 145 operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 146 return !(__x == __y); 147 } 148 #endif 149 150 // TODO(mordante) disable these overloads in the LLVM 20 release. 151 template <class _Iter1> 152 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 153 operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 154 return __y < __x; 155 } 156 157 template <class _Iter1, class _Iter2> 158 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 159 operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 160 return __y < __x; 161 } 162 163 template <class _Iter1> 164 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 165 operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 166 return !(__x < __y); 167 } 168 169 template <class _Iter1, class _Iter2> 170 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 171 operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 172 return !(__x < __y); 173 } 174 175 template <class _Iter1> 176 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 177 operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 178 return !(__y < __x); 179 } 180 181 template <class _Iter1, class _Iter2> 182 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 183 operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 184 return !(__y < __x); 185 } 186 187 #if _LIBCPP_STD_VER >= 20 188 template <class _Iter1, class _Iter2> 189 _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering 190 operator<=>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) noexcept { 191 if constexpr (three_way_comparable_with<_Iter1, _Iter2, strong_ordering>) { 192 return __x.base() <=> __y.base(); 193 } else { 194 if (__x.base() < __y.base()) 195 return strong_ordering::less; 196 197 if (__x.base() == __y.base()) 198 return strong_ordering::equal; 199 200 return strong_ordering::greater; 201 } 202 } 203 #endif // _LIBCPP_STD_VER >= 20 204 205 template <class _Iter1, class _Iter2> 206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 207 #ifndef _LIBCPP_CXX03_LANG 208 auto 209 operator-(const __wrap_iter<_Iter1>& __x, 210 const __wrap_iter<_Iter2>& __y) _NOEXCEPT->decltype(__x.base() - __y.base()) 211 #else 212 typename __wrap_iter<_Iter1>::difference_type 213 operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 214 #endif // C++03 215 { 216 return __x.base() - __y.base(); 217 } 218 219 template <class _Iter1> 220 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter<_Iter1> 221 operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT { 222 __x += __n; 223 return __x; 224 } 225 226 #if _LIBCPP_STD_VER <= 17 227 template <class _It> 228 struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {}; 229 #endif 230 231 template <class _It> 232 struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> > { 233 typedef __wrap_iter<_It> pointer; 234 typedef typename pointer_traits<_It>::element_type element_type; 235 typedef typename pointer_traits<_It>::difference_type difference_type; 236 237 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __w) _NOEXCEPT { 238 return std::__to_address(__w.base()); 239 } 240 }; 241 242 _LIBCPP_END_NAMESPACE_STD 243 244 #endif // _LIBCPP___ITERATOR_WRAP_ITER_H 245