254 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___ITERATOR_WRAP_ITER_H11#define _LIBCPP___ITERATOR_WRAP_ITER_H12 13#include <__compare/ordering.h>14#include <__compare/three_way_comparable.h>15#include <__config>16#include <__cstddef/size_t.h>17#include <__iterator/iterator_traits.h>18#include <__memory/addressof.h>19#include <__memory/pointer_traits.h>20#include <__type_traits/conjunction.h>21#include <__type_traits/disjunction.h>22#include <__type_traits/enable_if.h>23#include <__type_traits/integral_constant.h>24#include <__type_traits/is_convertible.h>25#include <__type_traits/is_same.h>26#include <__type_traits/make_const_lvalue_ref.h>27 28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)29# pragma GCC system_header30#endif31 32_LIBCPP_BEGIN_NAMESPACE_STD33 34template <class _Iter>35class __wrap_iter {36public:37 typedef _Iter iterator_type;38 typedef typename iterator_traits<iterator_type>::value_type value_type;39 typedef typename iterator_traits<iterator_type>::difference_type difference_type;40 typedef typename iterator_traits<iterator_type>::pointer pointer;41 typedef typename iterator_traits<iterator_type>::reference reference;42 typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;43#if _LIBCPP_STD_VER >= 2044 typedef contiguous_iterator_tag iterator_concept;45#endif46 47private:48 iterator_type __i_;49 50public:51 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT : __i_() {}52 template <class _OtherIter,53 __enable_if_t<54 _And<is_convertible<const _OtherIter&, _Iter>,55 _Or<is_same<reference, __iterator_reference<_OtherIter> >,56 is_same<reference, __make_const_lvalue_ref<__iterator_reference<_OtherIter> > > > >::value,57 int> = 0>58 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter(const __wrap_iter<_OtherIter>& __u) _NOEXCEPT59 : __i_(__u.__i_) {}60 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { return *__i_; }61 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT {62 return std::__to_address(__i_);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 74 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT {75 --__i_;76 return *this;77 }78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator--(int) _NOEXCEPT {79 __wrap_iter __tmp(*this);80 --(*this);81 return __tmp;82 }83 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator+(difference_type __n) const _NOEXCEPT {84 __wrap_iter __w(*this);85 __w += __n;86 return __w;87 }88 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT {89 __i_ += __n;90 return *this;91 }92 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator-(difference_type __n) const _NOEXCEPT {93 return *this + (-__n);94 }95 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT {96 *this += -__n;97 return *this;98 }99 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT {100 return __i_[__n];101 }102 103 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator_type base() const _NOEXCEPT { return __i_; }104 105private:106 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __wrap_iter(iterator_type __x) _NOEXCEPT : __i_(__x) {}107 108 template <class _Up>109 friend class __wrap_iter;110 template <class _CharT, class _Traits, class _Alloc>111 friend class basic_string;112 template <class _CharT, class _Traits>113 friend class basic_string_view;114 template <class _Tp, class _Alloc>115 friend class vector;116 template <class _Tp, size_t>117 friend class span;118 template <class _Tp, size_t _Size>119 friend struct array;120 template <class _Tp, class>121 friend struct __optional_iterator;122};123 124template <class _Iter1>125_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool126operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {127 return __x.base() == __y.base();128}129 130template <class _Iter1, class _Iter2>131_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool132operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {133 return __x.base() == __y.base();134}135 136template <class _Iter1>137_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool138operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {139 return __x.base() < __y.base();140}141 142template <class _Iter1, class _Iter2>143_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool144operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {145 return __x.base() < __y.base();146}147 148#if _LIBCPP_STD_VER <= 17149template <class _Iter1>150_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool151operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {152 return !(__x == __y);153}154 155template <class _Iter1, class _Iter2>156_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool157operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {158 return !(__x == __y);159}160template <class _Iter1>161_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool162operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {163 return __y < __x;164}165 166template <class _Iter1, class _Iter2>167_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool168operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {169 return __y < __x;170}171 172template <class _Iter1>173_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool174operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {175 return !(__x < __y);176}177 178template <class _Iter1, class _Iter2>179_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool180operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {181 return !(__x < __y);182}183 184template <class _Iter1>185_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool186operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {187 return !(__y < __x);188}189 190template <class _Iter1, class _Iter2>191_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool192operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {193 return !(__y < __x);194}195 196#else197template <class _Iter1, class _Iter2>198_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering199operator<=>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) noexcept {200 if constexpr (three_way_comparable_with<_Iter1, _Iter2, strong_ordering>) {201 return __x.base() <=> __y.base();202 } else {203 if (__x.base() < __y.base())204 return strong_ordering::less;205 206 if (__x.base() == __y.base())207 return strong_ordering::equal;208 209 return strong_ordering::greater;210 }211}212#endif // _LIBCPP_STD_VER >= 20213 214template <class _Iter1, class _Iter2>215_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14216#ifndef _LIBCPP_CXX03_LANG217 auto218 operator-(const __wrap_iter<_Iter1>& __x,219 const __wrap_iter<_Iter2>& __y) _NOEXCEPT->decltype(__x.base() - __y.base())220#else221typename __wrap_iter<_Iter1>::difference_type222operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT223#endif // C++03224{225 return __x.base() - __y.base();226}227 228template <class _Iter1>229_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter<_Iter1>230operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT {231 __x += __n;232 return __x;233}234 235#if _LIBCPP_STD_VER <= 17236template <class _It>237struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {};238#endif239 240template <class _It>241struct pointer_traits<__wrap_iter<_It> > {242 typedef __wrap_iter<_It> pointer;243 typedef typename pointer_traits<_It>::element_type element_type;244 typedef typename pointer_traits<_It>::difference_type difference_type;245 246 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __w) _NOEXCEPT {247 return std::__to_address(__w.base());248 }249};250 251_LIBCPP_END_NAMESPACE_STD252 253#endif // _LIBCPP___ITERATOR_WRAP_ITER_H254