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