176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
976d0caaeSpatrick
1076d0caaeSpatrick #ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
1176d0caaeSpatrick #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
1276d0caaeSpatrick
13*4bdff4beSrobert #include <__algorithm/unwrap_iter.h>
14*4bdff4beSrobert #include <__compare/compare_three_way_result.h>
15*4bdff4beSrobert #include <__compare/three_way_comparable.h>
16*4bdff4beSrobert #include <__concepts/convertible_to.h>
1776d0caaeSpatrick #include <__config>
18*4bdff4beSrobert #include <__iterator/advance.h>
19*4bdff4beSrobert #include <__iterator/concepts.h>
20*4bdff4beSrobert #include <__iterator/incrementable_traits.h>
21*4bdff4beSrobert #include <__iterator/iter_move.h>
22*4bdff4beSrobert #include <__iterator/iter_swap.h>
2376d0caaeSpatrick #include <__iterator/iterator.h>
2476d0caaeSpatrick #include <__iterator/iterator_traits.h>
25*4bdff4beSrobert #include <__iterator/next.h>
26*4bdff4beSrobert #include <__iterator/prev.h>
27*4bdff4beSrobert #include <__iterator/readable_traits.h>
28*4bdff4beSrobert #include <__iterator/segmented_iterator.h>
2976d0caaeSpatrick #include <__memory/addressof.h>
30*4bdff4beSrobert #include <__ranges/access.h>
31*4bdff4beSrobert #include <__ranges/concepts.h>
32*4bdff4beSrobert #include <__ranges/subrange.h>
33*4bdff4beSrobert #include <__type_traits/conditional.h>
34*4bdff4beSrobert #include <__type_traits/enable_if.h>
35*4bdff4beSrobert #include <__type_traits/is_assignable.h>
36*4bdff4beSrobert #include <__type_traits/is_convertible.h>
37*4bdff4beSrobert #include <__type_traits/is_nothrow_copy_constructible.h>
38*4bdff4beSrobert #include <__type_traits/is_pointer.h>
39*4bdff4beSrobert #include <__type_traits/is_same.h>
40*4bdff4beSrobert #include <__utility/declval.h>
41*4bdff4beSrobert #include <__utility/move.h>
4276d0caaeSpatrick
4376d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4476d0caaeSpatrick # pragma GCC system_header
4576d0caaeSpatrick #endif
4676d0caaeSpatrick
4776d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
4876d0caaeSpatrick
4976d0caaeSpatrick _LIBCPP_SUPPRESS_DEPRECATED_PUSH
5076d0caaeSpatrick template <class _Iter>
5176d0caaeSpatrick class _LIBCPP_TEMPLATE_VIS reverse_iterator
5276d0caaeSpatrick #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
5376d0caaeSpatrick : public iterator<typename iterator_traits<_Iter>::iterator_category,
5476d0caaeSpatrick typename iterator_traits<_Iter>::value_type,
5576d0caaeSpatrick typename iterator_traits<_Iter>::difference_type,
5676d0caaeSpatrick typename iterator_traits<_Iter>::pointer,
5776d0caaeSpatrick typename iterator_traits<_Iter>::reference>
5876d0caaeSpatrick #endif
5976d0caaeSpatrick {
6076d0caaeSpatrick _LIBCPP_SUPPRESS_DEPRECATED_POP
6176d0caaeSpatrick private:
6276d0caaeSpatrick #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
63*4bdff4beSrobert _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break
6476d0caaeSpatrick #endif
6576d0caaeSpatrick
66*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
67*4bdff4beSrobert static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>,
68*4bdff4beSrobert "reverse_iterator<It> requires It to be a bidirectional iterator.");
69*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
7076d0caaeSpatrick
7176d0caaeSpatrick protected:
7276d0caaeSpatrick _Iter current;
7376d0caaeSpatrick public:
74*4bdff4beSrobert using iterator_type = _Iter;
7576d0caaeSpatrick
76*4bdff4beSrobert using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value,
7776d0caaeSpatrick random_access_iterator_tag,
78*4bdff4beSrobert typename iterator_traits<_Iter>::iterator_category>;
79*4bdff4beSrobert using pointer = typename iterator_traits<_Iter>::pointer;
80*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
81*4bdff4beSrobert using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>;
82*4bdff4beSrobert using value_type = iter_value_t<_Iter>;
83*4bdff4beSrobert using difference_type = iter_difference_t<_Iter>;
84*4bdff4beSrobert using reference = iter_reference_t<_Iter>;
85*4bdff4beSrobert #else
86*4bdff4beSrobert using value_type = typename iterator_traits<_Iter>::value_type;
87*4bdff4beSrobert using difference_type = typename iterator_traits<_Iter>::difference_type;
88*4bdff4beSrobert using reference = typename iterator_traits<_Iter>::reference;
8976d0caaeSpatrick #endif
9076d0caaeSpatrick
9176d0caaeSpatrick #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
92*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator()93*4bdff4beSrobert reverse_iterator() : __t_(), current() {}
9476d0caaeSpatrick
95*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator(_Iter __x)96*4bdff4beSrobert explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {}
9776d0caaeSpatrick
98*4bdff4beSrobert template <class _Up, class = __enable_if_t<
9976d0caaeSpatrick !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
10076d0caaeSpatrick > >
101*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator(const reverse_iterator<_Up> & __u)10276d0caaeSpatrick reverse_iterator(const reverse_iterator<_Up>& __u)
103*4bdff4beSrobert : __t_(__u.base()), current(__u.base())
10476d0caaeSpatrick { }
10576d0caaeSpatrick
106*4bdff4beSrobert template <class _Up, class = __enable_if_t<
10776d0caaeSpatrick !is_same<_Up, _Iter>::value &&
10876d0caaeSpatrick is_convertible<_Up const&, _Iter>::value &&
109*4bdff4beSrobert is_assignable<_Iter&, _Up const&>::value
11076d0caaeSpatrick > >
111*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
11276d0caaeSpatrick reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
113*4bdff4beSrobert __t_ = current = __u.base();
11476d0caaeSpatrick return *this;
11576d0caaeSpatrick }
11676d0caaeSpatrick #else
117*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator()11876d0caaeSpatrick reverse_iterator() : current() {}
11976d0caaeSpatrick
120*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator(_Iter __x)12176d0caaeSpatrick explicit reverse_iterator(_Iter __x) : current(__x) {}
12276d0caaeSpatrick
123*4bdff4beSrobert template <class _Up, class = __enable_if_t<
12476d0caaeSpatrick !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
12576d0caaeSpatrick > >
126*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
reverse_iterator(const reverse_iterator<_Up> & __u)12776d0caaeSpatrick reverse_iterator(const reverse_iterator<_Up>& __u)
12876d0caaeSpatrick : current(__u.base())
12976d0caaeSpatrick { }
13076d0caaeSpatrick
131*4bdff4beSrobert template <class _Up, class = __enable_if_t<
13276d0caaeSpatrick !is_same<_Up, _Iter>::value &&
13376d0caaeSpatrick is_convertible<_Up const&, _Iter>::value &&
134*4bdff4beSrobert is_assignable<_Iter&, _Up const&>::value
13576d0caaeSpatrick > >
136*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
13776d0caaeSpatrick reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
13876d0caaeSpatrick current = __u.base();
13976d0caaeSpatrick return *this;
14076d0caaeSpatrick }
14176d0caaeSpatrick #endif
142*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
base()14376d0caaeSpatrick _Iter base() const {return current;}
144*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
14576d0caaeSpatrick reference operator*() const {_Iter __tmp = current; return *--__tmp;}
146*4bdff4beSrobert
147*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
148*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY
149*4bdff4beSrobert constexpr pointer operator->() const
150*4bdff4beSrobert requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); }
151*4bdff4beSrobert {
152*4bdff4beSrobert if constexpr (is_pointer_v<_Iter>) {
153*4bdff4beSrobert return std::prev(current);
154*4bdff4beSrobert } else {
155*4bdff4beSrobert return std::prev(current).operator->();
156*4bdff4beSrobert }
157*4bdff4beSrobert }
158*4bdff4beSrobert #else
159*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
160*4bdff4beSrobert pointer operator->() const {
161*4bdff4beSrobert return std::addressof(operator*());
162*4bdff4beSrobert }
163*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
164*4bdff4beSrobert
165*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
16676d0caaeSpatrick reverse_iterator& operator++() {--current; return *this;}
167*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
16876d0caaeSpatrick reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
169*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
17076d0caaeSpatrick reverse_iterator& operator--() {++current; return *this;}
171*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
17276d0caaeSpatrick reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
173*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
17476d0caaeSpatrick reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);}
175*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
17676d0caaeSpatrick reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
177*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
17876d0caaeSpatrick reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);}
179*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
18076d0caaeSpatrick reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
181*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
18276d0caaeSpatrick reference operator[](difference_type __n) const {return *(*this + __n);}
183*4bdff4beSrobert
184*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
185*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr
iter_move(const reverse_iterator & __i)186*4bdff4beSrobert iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i)
187*4bdff4beSrobert noexcept(is_nothrow_copy_constructible_v<_Iter> &&
188*4bdff4beSrobert noexcept(ranges::iter_move(--std::declval<_Iter&>()))) {
189*4bdff4beSrobert auto __tmp = __i.base();
190*4bdff4beSrobert return ranges::iter_move(--__tmp);
191*4bdff4beSrobert }
192*4bdff4beSrobert
193*4bdff4beSrobert template <indirectly_swappable<_Iter> _Iter2>
194*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr
iter_swap(const reverse_iterator & __x,const reverse_iterator<_Iter2> & __y)195*4bdff4beSrobert void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y)
196*4bdff4beSrobert noexcept(is_nothrow_copy_constructible_v<_Iter> &&
197*4bdff4beSrobert is_nothrow_copy_constructible_v<_Iter2> &&
198*4bdff4beSrobert noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) {
199*4bdff4beSrobert auto __xtmp = __x.base();
200*4bdff4beSrobert auto __ytmp = __y.base();
201*4bdff4beSrobert ranges::iter_swap(--__xtmp, --__ytmp);
202*4bdff4beSrobert }
203*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
20476d0caaeSpatrick };
20576d0caaeSpatrick
20676d0caaeSpatrick template <class _Iter1, class _Iter2>
207*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
20876d0caaeSpatrick bool
20976d0caaeSpatrick operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
210*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
211*4bdff4beSrobert requires requires {
212*4bdff4beSrobert { __x.base() == __y.base() } -> convertible_to<bool>;
213*4bdff4beSrobert }
214*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
21576d0caaeSpatrick {
21676d0caaeSpatrick return __x.base() == __y.base();
21776d0caaeSpatrick }
21876d0caaeSpatrick
21976d0caaeSpatrick template <class _Iter1, class _Iter2>
220*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
22176d0caaeSpatrick bool
22276d0caaeSpatrick operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
223*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
224*4bdff4beSrobert requires requires {
225*4bdff4beSrobert { __x.base() > __y.base() } -> convertible_to<bool>;
226*4bdff4beSrobert }
227*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
22876d0caaeSpatrick {
22976d0caaeSpatrick return __x.base() > __y.base();
23076d0caaeSpatrick }
23176d0caaeSpatrick
23276d0caaeSpatrick template <class _Iter1, class _Iter2>
233*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
23476d0caaeSpatrick bool
23576d0caaeSpatrick operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
236*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
237*4bdff4beSrobert requires requires {
238*4bdff4beSrobert { __x.base() != __y.base() } -> convertible_to<bool>;
239*4bdff4beSrobert }
240*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
24176d0caaeSpatrick {
24276d0caaeSpatrick return __x.base() != __y.base();
24376d0caaeSpatrick }
24476d0caaeSpatrick
24576d0caaeSpatrick template <class _Iter1, class _Iter2>
246*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
24776d0caaeSpatrick bool
24876d0caaeSpatrick operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
249*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
250*4bdff4beSrobert requires requires {
251*4bdff4beSrobert { __x.base() < __y.base() } -> convertible_to<bool>;
252*4bdff4beSrobert }
253*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
25476d0caaeSpatrick {
25576d0caaeSpatrick return __x.base() < __y.base();
25676d0caaeSpatrick }
25776d0caaeSpatrick
25876d0caaeSpatrick template <class _Iter1, class _Iter2>
259*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
26076d0caaeSpatrick bool
26176d0caaeSpatrick operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
262*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
263*4bdff4beSrobert requires requires {
264*4bdff4beSrobert { __x.base() <= __y.base() } -> convertible_to<bool>;
265*4bdff4beSrobert }
266*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
26776d0caaeSpatrick {
26876d0caaeSpatrick return __x.base() <= __y.base();
26976d0caaeSpatrick }
27076d0caaeSpatrick
27176d0caaeSpatrick template <class _Iter1, class _Iter2>
272*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
27376d0caaeSpatrick bool
27476d0caaeSpatrick operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
275*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
276*4bdff4beSrobert requires requires {
277*4bdff4beSrobert { __x.base() >= __y.base() } -> convertible_to<bool>;
278*4bdff4beSrobert }
279*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
28076d0caaeSpatrick {
28176d0caaeSpatrick return __x.base() >= __y.base();
28276d0caaeSpatrick }
28376d0caaeSpatrick
284*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
285*4bdff4beSrobert template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
286*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr
287*4bdff4beSrobert compare_three_way_result_t<_Iter1, _Iter2>
288*4bdff4beSrobert operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
289*4bdff4beSrobert {
290*4bdff4beSrobert return __y.base() <=> __x.base();
291*4bdff4beSrobert }
292*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
293*4bdff4beSrobert
29476d0caaeSpatrick #ifndef _LIBCPP_CXX03_LANG
29576d0caaeSpatrick template <class _Iter1, class _Iter2>
296*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
29776d0caaeSpatrick auto
29876d0caaeSpatrick operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
29976d0caaeSpatrick -> decltype(__y.base() - __x.base())
30076d0caaeSpatrick {
30176d0caaeSpatrick return __y.base() - __x.base();
30276d0caaeSpatrick }
30376d0caaeSpatrick #else
30476d0caaeSpatrick template <class _Iter1, class _Iter2>
30576d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
30676d0caaeSpatrick typename reverse_iterator<_Iter1>::difference_type
30776d0caaeSpatrick operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
30876d0caaeSpatrick {
30976d0caaeSpatrick return __y.base() - __x.base();
31076d0caaeSpatrick }
31176d0caaeSpatrick #endif
31276d0caaeSpatrick
31376d0caaeSpatrick template <class _Iter>
314*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
31576d0caaeSpatrick reverse_iterator<_Iter>
31676d0caaeSpatrick operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
31776d0caaeSpatrick {
31876d0caaeSpatrick return reverse_iterator<_Iter>(__x.base() - __n);
31976d0caaeSpatrick }
32076d0caaeSpatrick
321*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
322*4bdff4beSrobert template <class _Iter1, class _Iter2>
323*4bdff4beSrobert requires (!sized_sentinel_for<_Iter1, _Iter2>)
324*4bdff4beSrobert inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true;
325*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
326*4bdff4beSrobert
32776d0caaeSpatrick #if _LIBCPP_STD_VER > 11
32876d0caaeSpatrick template <class _Iter>
329*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
make_reverse_iterator(_Iter __i)33076d0caaeSpatrick reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
33176d0caaeSpatrick {
33276d0caaeSpatrick return reverse_iterator<_Iter>(__i);
33376d0caaeSpatrick }
33476d0caaeSpatrick #endif
33576d0caaeSpatrick
336*4bdff4beSrobert #if _LIBCPP_STD_VER <= 17
337*4bdff4beSrobert template <class _Iter>
338*4bdff4beSrobert using __unconstrained_reverse_iterator = reverse_iterator<_Iter>;
339*4bdff4beSrobert #else
34076d0caaeSpatrick
341*4bdff4beSrobert // __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working
342*4bdff4beSrobert // around a language issue in C++20.
343*4bdff4beSrobert // In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will
344*4bdff4beSrobert // result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not
345*4bdff4beSrobert // an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a
346*4bdff4beSrobert // C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with
347*4bdff4beSrobert // tweaks to make it support hostile iterators.
348*4bdff4beSrobert //
349*4bdff4beSrobert // A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match
350*4bdff4beSrobert // and the other requires an implicit conversion, for example:
351*4bdff4beSrobert // friend bool operator==(const BaseIter&, const DerivedIter&);
352*4bdff4beSrobert //
353*4bdff4beSrobert // C++20 rules for rewriting equality operators create another overload of this function with parameters reversed:
354*4bdff4beSrobert // friend bool operator==(const DerivedIter&, const BaseIter&);
355*4bdff4beSrobert //
356*4bdff4beSrobert // This creates an ambiguity in overload resolution.
357*4bdff4beSrobert //
358*4bdff4beSrobert // Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function
359*4bdff4beSrobert // body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however,
360*4bdff4beSrobert // it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its
361*4bdff4beSrobert // base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload
362*4bdff4beSrobert // resolution. This class simply removes the problematic constraints from comparison functions.
363*4bdff4beSrobert template <class _Iter>
364*4bdff4beSrobert class __unconstrained_reverse_iterator {
365*4bdff4beSrobert _Iter __iter_;
366*4bdff4beSrobert
367*4bdff4beSrobert public:
368*4bdff4beSrobert static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>);
369*4bdff4beSrobert
370*4bdff4beSrobert using iterator_type = _Iter;
371*4bdff4beSrobert using iterator_category =
372*4bdff4beSrobert _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>;
373*4bdff4beSrobert using pointer = __iterator_pointer_type<_Iter>;
374*4bdff4beSrobert using value_type = iter_value_t<_Iter>;
375*4bdff4beSrobert using difference_type = iter_difference_t<_Iter>;
376*4bdff4beSrobert using reference = iter_reference_t<_Iter>;
377*4bdff4beSrobert
378*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default;
379*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default;
__unconstrained_reverse_iterator(_Iter __iter)380*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {}
381*4bdff4beSrobert
base()382*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() const { return __iter_; }
383*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const {
384*4bdff4beSrobert auto __tmp = __iter_;
385*4bdff4beSrobert return *--__tmp;
386*4bdff4beSrobert }
387*4bdff4beSrobert
388*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const {
389*4bdff4beSrobert if constexpr (is_pointer_v<_Iter>) {
390*4bdff4beSrobert return std::prev(__iter_);
391*4bdff4beSrobert } else {
392*4bdff4beSrobert return std::prev(__iter_).operator->();
393*4bdff4beSrobert }
394*4bdff4beSrobert }
395*4bdff4beSrobert
396*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr
iter_move(const __unconstrained_reverse_iterator & __i)397*4bdff4beSrobert iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i)
398*4bdff4beSrobert noexcept(is_nothrow_copy_constructible_v<_Iter> &&
399*4bdff4beSrobert noexcept(ranges::iter_move(--std::declval<_Iter&>()))) {
400*4bdff4beSrobert auto __tmp = __i.base();
401*4bdff4beSrobert return ranges::iter_move(--__tmp);
402*4bdff4beSrobert }
403*4bdff4beSrobert
404*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() {
405*4bdff4beSrobert --__iter_;
406*4bdff4beSrobert return *this;
407*4bdff4beSrobert }
408*4bdff4beSrobert
409*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator++(int) {
410*4bdff4beSrobert auto __tmp = *this;
411*4bdff4beSrobert --__iter_;
412*4bdff4beSrobert return __tmp;
413*4bdff4beSrobert }
414*4bdff4beSrobert
415*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator--() {
416*4bdff4beSrobert ++__iter_;
417*4bdff4beSrobert return *this;
418*4bdff4beSrobert }
419*4bdff4beSrobert
420*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator--(int) {
421*4bdff4beSrobert auto __tmp = *this;
422*4bdff4beSrobert ++__iter_;
423*4bdff4beSrobert return __tmp;
424*4bdff4beSrobert }
425*4bdff4beSrobert
426*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator+=(difference_type __n) {
427*4bdff4beSrobert __iter_ -= __n;
428*4bdff4beSrobert return *this;
429*4bdff4beSrobert }
430*4bdff4beSrobert
431*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator-=(difference_type __n) {
432*4bdff4beSrobert __iter_ += __n;
433*4bdff4beSrobert return *this;
434*4bdff4beSrobert }
435*4bdff4beSrobert
436*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator+(difference_type __n) const {
437*4bdff4beSrobert return __unconstrained_reverse_iterator(__iter_ - __n);
438*4bdff4beSrobert }
439*4bdff4beSrobert
440*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator-(difference_type __n) const {
441*4bdff4beSrobert return __unconstrained_reverse_iterator(__iter_ + __n);
442*4bdff4beSrobert }
443*4bdff4beSrobert
444*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr difference_type operator-(const __unconstrained_reverse_iterator& __other) const {
445*4bdff4beSrobert return __other.__iter_ - __iter_;
446*4bdff4beSrobert }
447*4bdff4beSrobert
448*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const { return *(*this + __n); }
449*4bdff4beSrobert
450*4bdff4beSrobert // Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the
451*4bdff4beSrobert // rationale.
452*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool
453*4bdff4beSrobert operator==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
454*4bdff4beSrobert return __lhs.base() == __rhs.base();
455*4bdff4beSrobert }
456*4bdff4beSrobert
457*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool
458*4bdff4beSrobert operator!=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
459*4bdff4beSrobert return __lhs.base() != __rhs.base();
460*4bdff4beSrobert }
461*4bdff4beSrobert
462*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool
463*4bdff4beSrobert operator<(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
464*4bdff4beSrobert return __lhs.base() > __rhs.base();
465*4bdff4beSrobert }
466*4bdff4beSrobert
467*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool
468*4bdff4beSrobert operator>(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
469*4bdff4beSrobert return __lhs.base() < __rhs.base();
470*4bdff4beSrobert }
471*4bdff4beSrobert
472*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool
473*4bdff4beSrobert operator<=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
474*4bdff4beSrobert return __lhs.base() >= __rhs.base();
475*4bdff4beSrobert }
476*4bdff4beSrobert
477*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool
478*4bdff4beSrobert operator>=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
479*4bdff4beSrobert return __lhs.base() <= __rhs.base();
480*4bdff4beSrobert }
481*4bdff4beSrobert };
482*4bdff4beSrobert
483*4bdff4beSrobert #endif // _LIBCPP_STD_VER <= 17
484*4bdff4beSrobert
485*4bdff4beSrobert template <template <class> class _RevIter1, template <class> class _RevIter2, class _Iter>
486*4bdff4beSrobert struct __unwrap_reverse_iter_impl {
487*4bdff4beSrobert using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>()));
488*4bdff4beSrobert using _ReverseWrapper = _RevIter1<_RevIter2<_Iter> >;
489*4bdff4beSrobert
490*4bdff4beSrobert static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper
__rewrap__unwrap_reverse_iter_impl491*4bdff4beSrobert __rewrap(_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) {
492*4bdff4beSrobert return _ReverseWrapper(
493*4bdff4beSrobert _RevIter2<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap(__orig_iter.base().base(), __unwrapped_iter)));
494*4bdff4beSrobert }
495*4bdff4beSrobert
__unwrap__unwrap_reverse_iter_impl496*4bdff4beSrobert static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _UnwrappedIter __unwrap(_ReverseWrapper __i) _NOEXCEPT {
497*4bdff4beSrobert return __unwrap_iter_impl<_Iter>::__unwrap(__i.base().base());
498*4bdff4beSrobert }
499*4bdff4beSrobert };
500*4bdff4beSrobert
501*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
502*4bdff4beSrobert template <ranges::bidirectional_range _Range>
503*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr ranges::
504*4bdff4beSrobert subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>>
__reverse_range(_Range && __range)505*4bdff4beSrobert __reverse_range(_Range&& __range) {
506*4bdff4beSrobert auto __first = ranges::begin(__range);
507*4bdff4beSrobert return {std::make_reverse_iterator(ranges::next(__first, ranges::end(__range))), std::make_reverse_iterator(__first)};
508*4bdff4beSrobert }
509*4bdff4beSrobert #endif
510*4bdff4beSrobert
511*4bdff4beSrobert template <class _Iter, bool __b>
512*4bdff4beSrobert struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b>
513*4bdff4beSrobert : __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {};
514*4bdff4beSrobert
515*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
516*4bdff4beSrobert
517*4bdff4beSrobert template <class _Iter, bool __b>
518*4bdff4beSrobert struct __unwrap_iter_impl<reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
519*4bdff4beSrobert : __unwrap_reverse_iter_impl<reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
520*4bdff4beSrobert
521*4bdff4beSrobert template <class _Iter, bool __b>
522*4bdff4beSrobert struct __unwrap_iter_impl<__unconstrained_reverse_iterator<reverse_iterator<_Iter>>, __b>
523*4bdff4beSrobert : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, reverse_iterator, _Iter> {};
524*4bdff4beSrobert
525*4bdff4beSrobert template <class _Iter, bool __b>
526*4bdff4beSrobert struct __unwrap_iter_impl<__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
527*4bdff4beSrobert : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
528*4bdff4beSrobert
529*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
530*4bdff4beSrobert
531*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD
53276d0caaeSpatrick
53376d0caaeSpatrick #endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
534