2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___ITERATOR_WRAP_ITER_H
11 #define _LIBCPP___ITERATOR_WRAP_ITER_H
13 #include <__compare/ordering.h>
14 #include <__compare/three_way_comparable.h>
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>
23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24 # pragma GCC system_header
27 _LIBCPP_BEGIN_NAMESPACE_STD
29 template <class _Iter
>
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
;
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>
48 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__wrap_iter(const __wrap_iter
<_Up
>& __u
) _NOEXCEPT
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_
);
54 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
& operator++() _NOEXCEPT
{
58 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
operator++(int) _NOEXCEPT
{
59 __wrap_iter
__tmp(*this);
64 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
& operator--() _NOEXCEPT
{
68 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
operator--(int) _NOEXCEPT
{
69 __wrap_iter
__tmp(*this);
73 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
operator+(difference_type __n
) const _NOEXCEPT
{
74 __wrap_iter
__w(*this);
78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
& operator+=(difference_type __n
) _NOEXCEPT
{
82 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
operator-(difference_type __n
) const _NOEXCEPT
{
83 return *this + (-__n
);
85 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
& operator-=(difference_type __n
) _NOEXCEPT
{
89 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference
operator[](difference_type __n
) const _NOEXCEPT
{
93 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator_type
base() const _NOEXCEPT
{ return __i_
; }
96 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
explicit __wrap_iter(iterator_type __x
) _NOEXCEPT
: __i_(__x
) {}
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
>
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();
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();
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();
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();
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
);
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
);
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
{
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
{
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
{
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
{
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
{
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
{
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();
194 if (__x
.base() < __y
.base())
195 return strong_ordering::less
;
197 if (__x
.base() == __y
.base())
198 return strong_ordering::equal
;
200 return strong_ordering::greater
;
203 #endif // _LIBCPP_STD_VER >= 20
205 template <class _Iter1
, class _Iter2
>
206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
207 #ifndef _LIBCPP_CXX03_LANG
209 operator-(const __wrap_iter
<_Iter1
>& __x
,
210 const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
->decltype(__x
.base() - __y
.base())
212 typename __wrap_iter
<_Iter1
>::difference_type
213 operator-(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
216 return __x
.base() - __y
.base();
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
{
226 #if _LIBCPP_STD_VER <= 17
228 struct __libcpp_is_contiguous_iterator
<__wrap_iter
<_It
> > : true_type
{};
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
;
237 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
static element_type
* to_address(pointer __w
) _NOEXCEPT
{
238 return std::__to_address(__w
.base());
242 _LIBCPP_END_NAMESPACE_STD
244 #endif // _LIBCPP___ITERATOR_WRAP_ITER_H