xref: /freebsd-src/contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h (revision 36b606ae6aa4b24061096ba18582e0a08ccd5dba)
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