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 <__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_header
30#endif
31
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34template <class _Iter>
35class __wrap_iter {
36public:
37 typedef typename iterator_traits<_Iter>::value_type value_type;
38 typedef typename iterator_traits<_Iter>::difference_type difference_type;
39 typedef typename iterator_traits<_Iter>::pointer pointer;
40 typedef typename iterator_traits<_Iter>::reference reference;
41 typedef typename iterator_traits<_Iter>::iterator_category iterator_category;
42#if _LIBCPP_STD_VER >= 20
43 typedef contiguous_iterator_tag iterator_concept;
44#endif
45
46private:
47 _Iter __i_;
48
49 friend struct pointer_traits<__wrap_iter<_Iter> >;
50
51public:
52 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT : __i_() {}
53 template <class _OtherIter,
54 __enable_if_t<
55 _And<is_convertible<const _OtherIter&, _Iter>,
56 _Or<is_same<reference, __iterator_reference<_OtherIter> >,
57 is_same<reference, __make_const_lvalue_ref<__iterator_reference<_OtherIter> > > > >::value,
58 int> = 0>
59 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter(const __wrap_iter<_OtherIter>& __u) _NOEXCEPT
60 : __i_(__u.__i_) {}
61 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { return *__i_; }
62 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT {
63 return std::__to_address(__i_);
64 }
65 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT {
66 ++__i_;
67 return *this;
68 }
69 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator++(int) _NOEXCEPT {
70 __wrap_iter __tmp(*this);
71 ++(*this);
72 return __tmp;
73 }
74
75 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT {
76 --__i_;
77 return *this;
78 }
79 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator--(int) _NOEXCEPT {
80 __wrap_iter __tmp(*this);
81 --(*this);
82 return __tmp;
83 }
84 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator+(difference_type __n) const _NOEXCEPT {
85 __wrap_iter __w(*this);
86 __w += __n;
87 return __w;
88 }
89 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT {
90 __i_ += __n;
91 return *this;
92 }
93 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator-(difference_type __n) const _NOEXCEPT {
94 return *this + (-__n);
95 }
96 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT {
97 *this += -__n;
98 return *this;
99 }
100 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT {
101 return __i_[__n];
102 }
103
104private:
105 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __wrap_iter(_Iter __x) _NOEXCEPT : __i_(__x) {}
106
107 template <class _Up>
108 friend class __wrap_iter;
109 template <class _CharT, class _Traits, class _Alloc>
110 friend class basic_string;
111 template <class _CharT, class _Traits>
112 friend class basic_string_view;
113 template <class _Tp, class _Alloc>
114 friend class vector;
115 template <class _Tp, size_t>
116 friend class span;
117 template <class _Tp, size_t _Size>
118 friend struct array;
119
120 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
121 operator==(const __wrap_iter& __x, const __wrap_iter& __y) _NOEXCEPT {
122 return __x.__i_ == __y.__i_;
123 }
124
125 template <class _Iter2>
126 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
127 operator==(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
128 return __x.__i_ == __y.__i_;
129 }
130
131 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
132 operator<(const __wrap_iter& __x, const __wrap_iter& __y) _NOEXCEPT {
133 return __x.__i_ < __y.__i_;
134 }
135
136 template <class _Iter2>
137 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
138 operator<(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
139 return __x.__i_ < __y.__i_;
140 }
141
142#if _LIBCPP_STD_VER <= 17
143 _LIBCPP_HIDE_FROM_ABI friend
144 _LIBCPP_CONSTEXPR bool operator!=(const __wrap_iter& __x, const __wrap_iter& __y) _NOEXCEPT {
145 return !(__x == __y);
146 }
147
148 template <class _Iter2>
149 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
150 operator!=(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
151 return !(__x == __y);
152 }
153
154 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
155 operator>(const __wrap_iter& __x, const __wrap_iter& __y) _NOEXCEPT {
156 return __y < __x;
157 }
158
159 template <class _Iter2>
160 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
161 operator>(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
162 return __y < __x;
163 }
164
165 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
166 operator>=(const __wrap_iter& __x, const __wrap_iter& __y) _NOEXCEPT {
167 return !(__x < __y);
168 }
169
170 template <class _Iter2>
171 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
172 operator>=(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
173 return !(__x < __y);
174 }
175
176 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
177 operator<=(const __wrap_iter& __x, const __wrap_iter& __y) _NOEXCEPT {
178 return !(__y < __x);
179 }
180
181 template <class _Iter2>
182 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
183 operator<=(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
184 return !(__y < __x);
185 }
186
187#else
188 template <class _Iter2>
189 _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering
190 operator<=>(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) noexcept {
191 if constexpr (three_way_comparable_with<_Iter, _Iter2, strong_ordering>) {
192 return __x.__i_ <=> __y.__i_;
193 } else {
194 if (__x.__i_ < __y.__i_)
195 return strong_ordering::less;
196
197 if (__x.__i_ == __y.__i_)
198 return strong_ordering::equal;
199
200 return strong_ordering::greater;
201 }
202 }
203#endif // _LIBCPP_STD_VER >= 20
204
205#ifndef _LIBCPP_CXX03_LANG
206 template <class _Iter2>
207 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX14 auto
208 operator-(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT->decltype(__x.__i_ - __y.__i_)
209#else
210 template <class _Iter2>
211 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX14
212 typename __wrap_iter::difference_type operator-(const __wrap_iter& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
213#endif // C++03
214 {
215 return __x.__i_ - __y.__i_;
216 }
217
218 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter
219 operator+(typename __wrap_iter::difference_type __n, __wrap_iter __x) _NOEXCEPT {
220 __x += __n;
221 return __x;
222 }
223};
224
225#if _LIBCPP_STD_VER <= 17
226template <class _It>
227struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {};
228#endif
229
230template <class _It>
231struct pointer_traits<__wrap_iter<_It> > {
232 typedef __wrap_iter<_It> pointer;
233 typedef typename pointer_traits<_It>::element_type element_type;
234 typedef typename pointer_traits<_It>::difference_type difference_type;
235
236 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __w) _NOEXCEPT {
237 return std::__to_address(__w.__i_);
238 }
239};
240
241_LIBCPP_END_NAMESPACE_STD
242
243#endif // _LIBCPP___ITERATOR_WRAP_ITER_H
244