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 <__config>
14#include <__iterator/iterator_traits.h>
15#include <__memory/addressof.h>
16#include <__memory/pointer_traits.h>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_convertible.h>
19#include <cstddef>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#  pragma GCC system_header
23#endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26
27template <class _Iter>
28class __wrap_iter {
29public:
30  typedef _Iter iterator_type;
31  typedef typename iterator_traits<iterator_type>::value_type value_type;
32  typedef typename iterator_traits<iterator_type>::difference_type difference_type;
33  typedef typename iterator_traits<iterator_type>::pointer pointer;
34  typedef typename iterator_traits<iterator_type>::reference reference;
35  typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
36#if _LIBCPP_STD_VER >= 20
37  typedef contiguous_iterator_tag iterator_concept;
38#endif
39
40private:
41  iterator_type __i_;
42
43public:
44  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT : __i_() {}
45  template <class _Up, __enable_if_t<is_convertible<_Up, iterator_type>::value, int> = 0>
46  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter(const __wrap_iter<_Up>& __u) _NOEXCEPT
47      : __i_(__u.base()) {}
48  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { return *__i_; }
49  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT {
50    return std::__to_address(__i_);
51  }
52  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT {
53    ++__i_;
54    return *this;
55  }
56  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator++(int) _NOEXCEPT {
57    __wrap_iter __tmp(*this);
58    ++(*this);
59    return __tmp;
60  }
61
62  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT {
63    --__i_;
64    return *this;
65  }
66  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator--(int) _NOEXCEPT {
67    __wrap_iter __tmp(*this);
68    --(*this);
69    return __tmp;
70  }
71  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator+(difference_type __n) const _NOEXCEPT {
72    __wrap_iter __w(*this);
73    __w += __n;
74    return __w;
75  }
76  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT {
77    __i_ += __n;
78    return *this;
79  }
80  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter operator-(difference_type __n) const _NOEXCEPT {
81    return *this + (-__n);
82  }
83  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT {
84    *this += -__n;
85    return *this;
86  }
87  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT {
88    return __i_[__n];
89  }
90
91  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator_type base() const _NOEXCEPT { return __i_; }
92
93private:
94  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __wrap_iter(iterator_type __x) _NOEXCEPT : __i_(__x) {}
95
96  template <class _Up>
97  friend class __wrap_iter;
98  template <class _CharT, class _Traits, class _Alloc>
99  friend class basic_string;
100  template <class _Tp, class _Alloc>
101  friend class _LIBCPP_TEMPLATE_VIS vector;
102  template <class _Tp, size_t>
103  friend class _LIBCPP_TEMPLATE_VIS span;
104};
105
106template <class _Iter1>
107_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
108operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
109  return __x.base() == __y.base();
110}
111
112template <class _Iter1, class _Iter2>
113_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
114operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
115  return __x.base() == __y.base();
116}
117
118template <class _Iter1>
119_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
120operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
121  return __x.base() < __y.base();
122}
123
124template <class _Iter1, class _Iter2>
125_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
126operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
127  return __x.base() < __y.base();
128}
129
130template <class _Iter1>
131_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
132operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
133  return !(__x == __y);
134}
135
136template <class _Iter1, class _Iter2>
137_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
138operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
139  return !(__x == __y);
140}
141
142template <class _Iter1>
143_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
144operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
145  return __y < __x;
146}
147
148template <class _Iter1, class _Iter2>
149_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
150operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
151  return __y < __x;
152}
153
154template <class _Iter1>
155_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
156operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
157  return !(__x < __y);
158}
159
160template <class _Iter1, class _Iter2>
161_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
162operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
163  return !(__x < __y);
164}
165
166template <class _Iter1>
167_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
168operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
169  return !(__y < __x);
170}
171
172template <class _Iter1, class _Iter2>
173_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
174operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
175  return !(__y < __x);
176}
177
178template <class _Iter1, class _Iter2>
179_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
180#ifndef _LIBCPP_CXX03_LANG
181    auto
182    operator-(const __wrap_iter<_Iter1>& __x,
183              const __wrap_iter<_Iter2>& __y) _NOEXCEPT->decltype(__x.base() - __y.base())
184#else
185    typename __wrap_iter<_Iter1>::difference_type
186    operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
187#endif // C++03
188{
189  return __x.base() - __y.base();
190}
191
192template <class _Iter1>
193_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter<_Iter1>
194operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT {
195  __x += __n;
196  return __x;
197}
198
199#if _LIBCPP_STD_VER <= 17
200template <class _It>
201struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {};
202#endif
203
204template <class _It>
205struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> > {
206  typedef __wrap_iter<_It> pointer;
207  typedef typename pointer_traits<_It>::element_type element_type;
208  typedef typename pointer_traits<_It>::difference_type difference_type;
209
210  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __w) _NOEXCEPT {
211    return std::__to_address(__w.base());
212  }
213};
214
215_LIBCPP_END_NAMESPACE_STD
216
217#endif // _LIBCPP___ITERATOR_WRAP_ITER_H
218