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 <__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>
28 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29 # pragma GCC system_header
32 _LIBCPP_BEGIN_NAMESPACE_STD
34 template <class _Iter
>
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 >= 20
44 typedef contiguous_iterator_tag iterator_concept
;
51 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__wrap_iter() _NOEXCEPT
: __i_() {}
54 __enable_if_t
< _And
< is_convertible
<const _OtherIter
&, _Iter
>,
55 _Or
<is_same
<reference
, __iter_reference
<_OtherIter
> >,
56 is_same
<reference
, __make_const_lvalue_ref
<__iter_reference
<_OtherIter
> > > > >::value
,
58 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__wrap_iter(const __wrap_iter
<_OtherIter
>& __u
) _NOEXCEPT
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_
);
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);
74 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
& operator--() _NOEXCEPT
{
78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
operator--(int) _NOEXCEPT
{
79 __wrap_iter
__tmp(*this);
83 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
operator+(difference_type __n
) const _NOEXCEPT
{
84 __wrap_iter
__w(*this);
88 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
& operator+=(difference_type __n
) _NOEXCEPT
{
92 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
operator-(difference_type __n
) const _NOEXCEPT
{
93 return *this + (-__n
);
95 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
& operator-=(difference_type __n
) _NOEXCEPT
{
99 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference
operator[](difference_type __n
) const _NOEXCEPT
{
103 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator_type
base() const _NOEXCEPT
{ return __i_
; }
106 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
explicit __wrap_iter(iterator_type __x
) _NOEXCEPT
: __i_(__x
) {}
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 _LIBCPP_TEMPLATE_VIS vector
;
116 template <class _Tp
, size_t>
117 friend class _LIBCPP_TEMPLATE_VIS span
;
118 template <class _Tp
, size_t _Size
>
122 template <class _Iter1
>
123 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
124 operator==(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter1
>& __y
) _NOEXCEPT
{
125 return __x
.base() == __y
.base();
128 template <class _Iter1
, class _Iter2
>
129 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
130 operator==(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
{
131 return __x
.base() == __y
.base();
134 template <class _Iter1
>
135 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
bool
136 operator<(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter1
>& __y
) _NOEXCEPT
{
137 return __x
.base() < __y
.base();
140 template <class _Iter1
, class _Iter2
>
141 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
bool
142 operator<(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
{
143 return __x
.base() < __y
.base();
146 #if _LIBCPP_STD_VER <= 17
147 template <class _Iter1
>
148 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
149 operator!=(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter1
>& __y
) _NOEXCEPT
{
150 return !(__x
== __y
);
153 template <class _Iter1
, class _Iter2
>
154 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
155 operator!=(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
{
156 return !(__x
== __y
);
158 template <class _Iter1
>
159 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
160 operator>(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter1
>& __y
) _NOEXCEPT
{
164 template <class _Iter1
, class _Iter2
>
165 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
166 operator>(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
{
170 template <class _Iter1
>
171 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
172 operator>=(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter1
>& __y
) _NOEXCEPT
{
176 template <class _Iter1
, class _Iter2
>
177 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
178 operator>=(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
{
182 template <class _Iter1
>
183 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
184 operator<=(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter1
>& __y
) _NOEXCEPT
{
188 template <class _Iter1
, class _Iter2
>
189 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool
190 operator<=(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
{
195 template <class _Iter1
, class _Iter2
>
196 _LIBCPP_HIDE_FROM_ABI
constexpr strong_ordering
197 operator<=>(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) noexcept
{
198 if constexpr (three_way_comparable_with
<_Iter1
, _Iter2
, strong_ordering
>) {
199 return __x
.base() <=> __y
.base();
201 if (__x
.base() < __y
.base())
202 return strong_ordering::less
;
204 if (__x
.base() == __y
.base())
205 return strong_ordering::equal
;
207 return strong_ordering::greater
;
210 #endif // _LIBCPP_STD_VER >= 20
212 template <class _Iter1
, class _Iter2
>
213 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
214 #ifndef _LIBCPP_CXX03_LANG
216 operator-(const __wrap_iter
<_Iter1
>& __x
,
217 const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
->decltype(__x
.base() - __y
.base())
219 typename __wrap_iter
<_Iter1
>::difference_type
220 operator-(const __wrap_iter
<_Iter1
>& __x
, const __wrap_iter
<_Iter2
>& __y
) _NOEXCEPT
223 return __x
.base() - __y
.base();
226 template <class _Iter1
>
227 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
<_Iter1
>
228 operator+(typename __wrap_iter
<_Iter1
>::difference_type __n
, __wrap_iter
<_Iter1
> __x
) _NOEXCEPT
{
233 #if _LIBCPP_STD_VER <= 17
235 struct __libcpp_is_contiguous_iterator
<__wrap_iter
<_It
> > : true_type
{};
239 struct _LIBCPP_TEMPLATE_VIS pointer_traits
<__wrap_iter
<_It
> > {
240 typedef __wrap_iter
<_It
> pointer
;
241 typedef typename pointer_traits
<_It
>::element_type element_type
;
242 typedef typename pointer_traits
<_It
>::difference_type difference_type
;
244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
static element_type
* to_address(pointer __w
) _NOEXCEPT
{
245 return std::__to_address(__w
.base());
249 _LIBCPP_END_NAMESPACE_STD
251 #endif // _LIBCPP___ITERATOR_WRAP_ITER_H