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 <__iterator/iterator_traits.h> 15#include <__memory/addressof.h> 16#include <__memory/pointer_traits.h> 17#include <__type_traits/enable_if.h> 18#include <__type_traits/is_convertible.h> 19#include <cstddef> 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 { 29public: 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 >= 20 37 typedef contiguous_iterator_tag iterator_concept; 38#endif 39 40private: 41 iterator_type __i_; 42 43public: 44 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT : __i_() {} 45 template <class _Up, __enable_if_t<is_convertible<_Up, iterator_type>::value, int> = 0> 46 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter(const __wrap_iter<_Up>& __u) _NOEXCEPT 47 : __i_(__u.base()) {} 48 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { return *__i_; } 49 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { 50 return std::__to_address(__i_); 51 } 52 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT { 53 ++__i_; 54 return *this; 55 } 56 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator++(int) _NOEXCEPT { 57 __wrap_iter __tmp(*this); 58 ++(*this); 59 return __tmp; 60 } 61 62 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT { 63 --__i_; 64 return *this; 65 } 66 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator--(int) _NOEXCEPT { 67 __wrap_iter __tmp(*this); 68 --(*this); 69 return __tmp; 70 } 71 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator+(difference_type __n) const _NOEXCEPT { 72 __wrap_iter __w(*this); 73 __w += __n; 74 return __w; 75 } 76 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT { 77 __i_ += __n; 78 return *this; 79 } 80 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator-(difference_type __n) const _NOEXCEPT { 81 return *this + (-__n); 82 } 83 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT { 84 *this += -__n; 85 return *this; 86 } 87 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { 88 return __i_[__n]; 89 } 90 91 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator_type base() const _NOEXCEPT { return __i_; } 92 93private: 94 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __wrap_iter(iterator_type __x) _NOEXCEPT : __i_(__x) {} 95 96 template <class _Up> 97 friend class __wrap_iter; 98 template <class _CharT, class _Traits, class _Alloc> 99 friend class basic_string; 100 template <class _Tp, class _Alloc> 101 friend class _LIBCPP_TEMPLATE_VIS vector; 102 template <class _Tp, size_t> 103 friend class _LIBCPP_TEMPLATE_VIS span; 104}; 105 106template <class _Iter1> 107_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 108operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 109 return __x.base() == __y.base(); 110} 111 112template <class _Iter1, class _Iter2> 113_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 114operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 115 return __x.base() == __y.base(); 116} 117 118template <class _Iter1> 119_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 120operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 121 return __x.base() < __y.base(); 122} 123 124template <class _Iter1, class _Iter2> 125_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 126operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 127 return __x.base() < __y.base(); 128} 129 130template <class _Iter1> 131_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 132operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 133 return !(__x == __y); 134} 135 136template <class _Iter1, class _Iter2> 137_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 138operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 139 return !(__x == __y); 140} 141 142template <class _Iter1> 143_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 144operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 145 return __y < __x; 146} 147 148template <class _Iter1, class _Iter2> 149_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 150operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 151 return __y < __x; 152} 153 154template <class _Iter1> 155_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 156operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 157 return !(__x < __y); 158} 159 160template <class _Iter1, class _Iter2> 161_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 162operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 163 return !(__x < __y); 164} 165 166template <class _Iter1> 167_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 168operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { 169 return !(__y < __x); 170} 171 172template <class _Iter1, class _Iter2> 173_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 174operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { 175 return !(__y < __x); 176} 177 178template <class _Iter1, class _Iter2> 179_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 180#ifndef _LIBCPP_CXX03_LANG 181 auto 182 operator-(const __wrap_iter<_Iter1>& __x, 183 const __wrap_iter<_Iter2>& __y) _NOEXCEPT->decltype(__x.base() - __y.base()) 184#else 185 typename __wrap_iter<_Iter1>::difference_type 186 operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT 187#endif // C++03 188{ 189 return __x.base() - __y.base(); 190} 191 192template <class _Iter1> 193_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter<_Iter1> 194operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT { 195 __x += __n; 196 return __x; 197} 198 199#if _LIBCPP_STD_VER <= 17 200template <class _It> 201struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {}; 202#endif 203 204template <class _It> 205struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> > { 206 typedef __wrap_iter<_It> pointer; 207 typedef typename pointer_traits<_It>::element_type element_type; 208 typedef typename pointer_traits<_It>::difference_type difference_type; 209 210 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __w) _NOEXCEPT { 211 return std::__to_address(__w.base()); 212 } 213}; 214 215_LIBCPP_END_NAMESPACE_STD 216 217#endif // _LIBCPP___ITERATOR_WRAP_ITER_H 218