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_REVERSE_ITERATOR_H
11 #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
12 
13 #include <__compare/compare_three_way_result.h>
14 #include <__compare/three_way_comparable.h>
15 #include <__config>
16 #include <__iterator/iterator.h>
17 #include <__iterator/iterator_traits.h>
18 #include <__memory/addressof.h>
19 #include <type_traits>
20 
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 #  pragma GCC system_header
23 #  pragma clang include_instead(<iterator>)
24 #endif
25 
26 _LIBCPP_BEGIN_NAMESPACE_STD
27 
28 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
29 template <class _Iter>
30 class _LIBCPP_TEMPLATE_VIS reverse_iterator
31 #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
32     : public iterator<typename iterator_traits<_Iter>::iterator_category,
33                       typename iterator_traits<_Iter>::value_type,
34                       typename iterator_traits<_Iter>::difference_type,
35                       typename iterator_traits<_Iter>::pointer,
36                       typename iterator_traits<_Iter>::reference>
37 #endif
38 {
39 _LIBCPP_SUPPRESS_DEPRECATED_POP
40 private:
41 #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
42     _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
43 #endif
44 
45 protected:
46     _Iter current;
47 public:
48     typedef _Iter                                            iterator_type;
49     typedef typename iterator_traits<_Iter>::difference_type difference_type;
50     typedef typename iterator_traits<_Iter>::reference       reference;
51     typedef typename iterator_traits<_Iter>::pointer         pointer;
52     typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
53         random_access_iterator_tag,
54         typename iterator_traits<_Iter>::iterator_category>  iterator_category;
55     typedef typename iterator_traits<_Iter>::value_type      value_type;
56 
57 #if _LIBCPP_STD_VER > 17
58     typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
59         random_access_iterator_tag,
60         bidirectional_iterator_tag>                          iterator_concept;
61 #endif
62 
63 #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
64     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
65     reverse_iterator() : __t(), current() {}
66 
67     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
68     explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
69 
70     template <class _Up, class = __enable_if_t<
71         !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
72     > >
73     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
74     reverse_iterator(const reverse_iterator<_Up>& __u)
75         : __t(__u.base()), current(__u.base())
76     { }
77 
78     template <class _Up, class = __enable_if_t<
79         !is_same<_Up, _Iter>::value &&
80         is_convertible<_Up const&, _Iter>::value &&
81         is_assignable<_Iter&, _Up const&>::value
82     > >
83     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
84     reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
85         __t = current = __u.base();
86         return *this;
87     }
88 #else
89     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
90     reverse_iterator() : current() {}
91 
92     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
93     explicit reverse_iterator(_Iter __x) : current(__x) {}
94 
95     template <class _Up, class = __enable_if_t<
96         !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
97     > >
98     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
99     reverse_iterator(const reverse_iterator<_Up>& __u)
100         : current(__u.base())
101     { }
102 
103     template <class _Up, class = __enable_if_t<
104         !is_same<_Up, _Iter>::value &&
105         is_convertible<_Up const&, _Iter>::value &&
106         is_assignable<_Iter&, _Up const&>::value
107     > >
108     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
109     reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
110         current = __u.base();
111         return *this;
112     }
113 #endif
114     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
115     _Iter base() const {return current;}
116     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
117     reference operator*() const {_Iter __tmp = current; return *--__tmp;}
118     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
119     pointer  operator->() const {return _VSTD::addressof(operator*());}
120     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
121     reverse_iterator& operator++() {--current; return *this;}
122     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
123     reverse_iterator  operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
124     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
125     reverse_iterator& operator--() {++current; return *this;}
126     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
127     reverse_iterator  operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
128     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
129     reverse_iterator  operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
130     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
131     reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
132     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
133     reverse_iterator  operator- (difference_type __n) const {return reverse_iterator(current + __n);}
134     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
135     reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
136     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
137     reference         operator[](difference_type __n) const {return *(*this + __n);}
138 };
139 
140 template <class _Iter1, class _Iter2>
141 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
142 bool
143 operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
144 {
145     return __x.base() == __y.base();
146 }
147 
148 template <class _Iter1, class _Iter2>
149 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
150 bool
151 operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
152 {
153     return __x.base() > __y.base();
154 }
155 
156 template <class _Iter1, class _Iter2>
157 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
158 bool
159 operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
160 {
161     return __x.base() != __y.base();
162 }
163 
164 template <class _Iter1, class _Iter2>
165 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
166 bool
167 operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
168 {
169     return __x.base() < __y.base();
170 }
171 
172 template <class _Iter1, class _Iter2>
173 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
174 bool
175 operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
176 {
177     return __x.base() <= __y.base();
178 }
179 
180 template <class _Iter1, class _Iter2>
181 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
182 bool
183 operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
184 {
185     return __x.base() >= __y.base();
186 }
187 
188 #if !defined(_LIBCPP_HAS_NO_CONCEPTS)
189 template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
190 _LIBCPP_HIDE_FROM_ABI constexpr
191 compare_three_way_result_t<_Iter1, _Iter2>
192 operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
193 {
194     return __y.base() <=> __x.base();
195 }
196 #endif
197 
198 #ifndef _LIBCPP_CXX03_LANG
199 template <class _Iter1, class _Iter2>
200 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
201 auto
202 operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
203 -> decltype(__y.base() - __x.base())
204 {
205     return __y.base() - __x.base();
206 }
207 #else
208 template <class _Iter1, class _Iter2>
209 inline _LIBCPP_INLINE_VISIBILITY
210 typename reverse_iterator<_Iter1>::difference_type
211 operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
212 {
213     return __y.base() - __x.base();
214 }
215 #endif
216 
217 template <class _Iter>
218 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
219 reverse_iterator<_Iter>
220 operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
221 {
222     return reverse_iterator<_Iter>(__x.base() - __n);
223 }
224 
225 #if _LIBCPP_STD_VER > 11
226 template <class _Iter>
227 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
228 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
229 {
230     return reverse_iterator<_Iter>(__i);
231 }
232 #endif
233 
234 _LIBCPP_END_NAMESPACE_STD
235 
236 #endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
237