1f32f3db9SLouis Dionne // -*- C++ -*- 2f32f3db9SLouis Dionne //===----------------------------------------------------------------------===// 3f32f3db9SLouis Dionne // 4f32f3db9SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5f32f3db9SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 6f32f3db9SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7f32f3db9SLouis Dionne // 8f32f3db9SLouis Dionne //===----------------------------------------------------------------------===// 9f32f3db9SLouis Dionne 10f32f3db9SLouis Dionne #ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 11f32f3db9SLouis Dionne #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 12f32f3db9SLouis Dionne 13fb3477a4SNikolas Klauser #include <__algorithm/unwrap_iter.h> 14d8f3cdfeSMikhail Maltsev #include <__compare/compare_three_way_result.h> 15d8f3cdfeSMikhail Maltsev #include <__compare/three_way_comparable.h> 16658957c7SKonstantin Varlamov #include <__concepts/convertible_to.h> 174d81a46fSArthur O'Dwyer #include <__config> 187d426a39SNikolas Klauser #include <__iterator/advance.h> 19658957c7SKonstantin Varlamov #include <__iterator/concepts.h> 20658957c7SKonstantin Varlamov #include <__iterator/incrementable_traits.h> 21658957c7SKonstantin Varlamov #include <__iterator/iter_move.h> 22658957c7SKonstantin Varlamov #include <__iterator/iter_swap.h> 23f32f3db9SLouis Dionne #include <__iterator/iterator.h> 248517a26dSChristopher Di Bella #include <__iterator/iterator_traits.h> 257d426a39SNikolas Klauser #include <__iterator/next.h> 26658957c7SKonstantin Varlamov #include <__iterator/prev.h> 27658957c7SKonstantin Varlamov #include <__iterator/readable_traits.h> 28f32f3db9SLouis Dionne #include <__memory/addressof.h> 297d426a39SNikolas Klauser #include <__ranges/access.h> 307d426a39SNikolas Klauser #include <__ranges/concepts.h> 317d426a39SNikolas Klauser #include <__ranges/subrange.h> 32658957c7SKonstantin Varlamov #include <__utility/move.h> 33f32f3db9SLouis Dionne #include <type_traits> 34f32f3db9SLouis Dionne 35f32f3db9SLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 36f32f3db9SLouis Dionne # pragma GCC system_header 37f32f3db9SLouis Dionne #endif 38f32f3db9SLouis Dionne 39f32f3db9SLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD 40f32f3db9SLouis Dionne 41f32f3db9SLouis Dionne _LIBCPP_SUPPRESS_DEPRECATED_PUSH 42f32f3db9SLouis Dionne template <class _Iter> 43f32f3db9SLouis Dionne class _LIBCPP_TEMPLATE_VIS reverse_iterator 44f32f3db9SLouis Dionne #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) 45f32f3db9SLouis Dionne : public iterator<typename iterator_traits<_Iter>::iterator_category, 46f32f3db9SLouis Dionne typename iterator_traits<_Iter>::value_type, 47f32f3db9SLouis Dionne typename iterator_traits<_Iter>::difference_type, 48f32f3db9SLouis Dionne typename iterator_traits<_Iter>::pointer, 49f32f3db9SLouis Dionne typename iterator_traits<_Iter>::reference> 50f32f3db9SLouis Dionne #endif 51f32f3db9SLouis Dionne { 52f32f3db9SLouis Dionne _LIBCPP_SUPPRESS_DEPRECATED_POP 53f32f3db9SLouis Dionne private: 54f32f3db9SLouis Dionne #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES 55f32f3db9SLouis Dionne _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break 56f32f3db9SLouis Dionne #endif 57f32f3db9SLouis Dionne 58658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 59658957c7SKonstantin Varlamov static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>, 60658957c7SKonstantin Varlamov "reverse_iterator<It> requires It to be a bidirectional iterator."); 61658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 62658957c7SKonstantin Varlamov 63f32f3db9SLouis Dionne protected: 64f32f3db9SLouis Dionne _Iter current; 65f32f3db9SLouis Dionne public: 66658957c7SKonstantin Varlamov using iterator_type = _Iter; 67f32f3db9SLouis Dionne 68658957c7SKonstantin Varlamov using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value, 69f32f3db9SLouis Dionne random_access_iterator_tag, 70658957c7SKonstantin Varlamov typename iterator_traits<_Iter>::iterator_category>; 71658957c7SKonstantin Varlamov using pointer = typename iterator_traits<_Iter>::pointer; 72658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 7336fb5430SNikolas Klauser using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>; 74658957c7SKonstantin Varlamov using value_type = iter_value_t<_Iter>; 75658957c7SKonstantin Varlamov using difference_type = iter_difference_t<_Iter>; 76658957c7SKonstantin Varlamov using reference = iter_reference_t<_Iter>; 77658957c7SKonstantin Varlamov #else 78658957c7SKonstantin Varlamov using value_type = typename iterator_traits<_Iter>::value_type; 79658957c7SKonstantin Varlamov using difference_type = typename iterator_traits<_Iter>::difference_type; 80658957c7SKonstantin Varlamov using reference = typename iterator_traits<_Iter>::reference; 81f32f3db9SLouis Dionne #endif 82f32f3db9SLouis Dionne 83f32f3db9SLouis Dionne #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES 84f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator()85f32f3db9SLouis Dionne reverse_iterator() : __t(), current() {} 86f32f3db9SLouis Dionne 87f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator(_Iter __x)88f32f3db9SLouis Dionne explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} 89f32f3db9SLouis Dionne 90b4e88d4dSLouis Dionne template <class _Up, class = __enable_if_t< 91f32f3db9SLouis Dionne !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value 92f32f3db9SLouis Dionne > > 93f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator(const reverse_iterator<_Up> & __u)94f32f3db9SLouis Dionne reverse_iterator(const reverse_iterator<_Up>& __u) 95f32f3db9SLouis Dionne : __t(__u.base()), current(__u.base()) 96f32f3db9SLouis Dionne { } 97f32f3db9SLouis Dionne 98b4e88d4dSLouis Dionne template <class _Up, class = __enable_if_t< 99f32f3db9SLouis Dionne !is_same<_Up, _Iter>::value && 100f32f3db9SLouis Dionne is_convertible<_Up const&, _Iter>::value && 1018c98ce4dSArthur O'Dwyer is_assignable<_Iter&, _Up const&>::value 102f32f3db9SLouis Dionne > > 103f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 104f32f3db9SLouis Dionne reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { 105f32f3db9SLouis Dionne __t = current = __u.base(); 106f32f3db9SLouis Dionne return *this; 107f32f3db9SLouis Dionne } 108f32f3db9SLouis Dionne #else 109f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator()110f32f3db9SLouis Dionne reverse_iterator() : current() {} 111f32f3db9SLouis Dionne 112f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator(_Iter __x)113f32f3db9SLouis Dionne explicit reverse_iterator(_Iter __x) : current(__x) {} 114f32f3db9SLouis Dionne 115b4e88d4dSLouis Dionne template <class _Up, class = __enable_if_t< 116f32f3db9SLouis Dionne !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value 117f32f3db9SLouis Dionne > > 118f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator(const reverse_iterator<_Up> & __u)119f32f3db9SLouis Dionne reverse_iterator(const reverse_iterator<_Up>& __u) 120f32f3db9SLouis Dionne : current(__u.base()) 121f32f3db9SLouis Dionne { } 122f32f3db9SLouis Dionne 123b4e88d4dSLouis Dionne template <class _Up, class = __enable_if_t< 124f32f3db9SLouis Dionne !is_same<_Up, _Iter>::value && 125f32f3db9SLouis Dionne is_convertible<_Up const&, _Iter>::value && 1268c98ce4dSArthur O'Dwyer is_assignable<_Iter&, _Up const&>::value 127f32f3db9SLouis Dionne > > 128f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 129f32f3db9SLouis Dionne reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { 130f32f3db9SLouis Dionne current = __u.base(); 131f32f3db9SLouis Dionne return *this; 132f32f3db9SLouis Dionne } 133f32f3db9SLouis Dionne #endif 134f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 base()135f32f3db9SLouis Dionne _Iter base() const {return current;} 136f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 137f32f3db9SLouis Dionne reference operator*() const {_Iter __tmp = current; return *--__tmp;} 138658957c7SKonstantin Varlamov 139658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 140658957c7SKonstantin Varlamov _LIBCPP_INLINE_VISIBILITY 141658957c7SKonstantin Varlamov constexpr pointer operator->() const 142b48c5010SNikolas Klauser requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } 143658957c7SKonstantin Varlamov { 144658957c7SKonstantin Varlamov if constexpr (is_pointer_v<_Iter>) { 145658957c7SKonstantin Varlamov return std::prev(current); 146658957c7SKonstantin Varlamov } else { 147658957c7SKonstantin Varlamov return std::prev(current).operator->(); 148658957c7SKonstantin Varlamov } 149658957c7SKonstantin Varlamov } 150658957c7SKonstantin Varlamov #else 151f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 152658957c7SKonstantin Varlamov pointer operator->() const { 153658957c7SKonstantin Varlamov return std::addressof(operator*()); 154658957c7SKonstantin Varlamov } 155658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 156658957c7SKonstantin Varlamov 157f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 158f32f3db9SLouis Dionne reverse_iterator& operator++() {--current; return *this;} 159f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 160f32f3db9SLouis Dionne reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} 161f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 162f32f3db9SLouis Dionne reverse_iterator& operator--() {++current; return *this;} 163f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 164f32f3db9SLouis Dionne reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} 165f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 166f32f3db9SLouis Dionne reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);} 167f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 168f32f3db9SLouis Dionne reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} 169f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 170f32f3db9SLouis Dionne reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);} 171f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 172f32f3db9SLouis Dionne reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} 173f32f3db9SLouis Dionne _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 174f32f3db9SLouis Dionne reference operator[](difference_type __n) const {return *(*this + __n);} 175658957c7SKonstantin Varlamov 176658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 177658957c7SKonstantin Varlamov _LIBCPP_HIDE_FROM_ABI friend constexpr iter_move(const reverse_iterator & __i)178658957c7SKonstantin Varlamov iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) 179658957c7SKonstantin Varlamov noexcept(is_nothrow_copy_constructible_v<_Iter> && 180658957c7SKonstantin Varlamov noexcept(ranges::iter_move(--declval<_Iter&>()))) { 181658957c7SKonstantin Varlamov auto __tmp = __i.base(); 182658957c7SKonstantin Varlamov return ranges::iter_move(--__tmp); 183658957c7SKonstantin Varlamov } 184658957c7SKonstantin Varlamov 185658957c7SKonstantin Varlamov template <indirectly_swappable<_Iter> _Iter2> 186658957c7SKonstantin Varlamov _LIBCPP_HIDE_FROM_ABI friend constexpr iter_swap(const reverse_iterator & __x,const reverse_iterator<_Iter2> & __y)187658957c7SKonstantin Varlamov void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) 188658957c7SKonstantin Varlamov noexcept(is_nothrow_copy_constructible_v<_Iter> && 189658957c7SKonstantin Varlamov is_nothrow_copy_constructible_v<_Iter2> && 190658957c7SKonstantin Varlamov noexcept(ranges::iter_swap(--declval<_Iter&>(), --declval<_Iter2&>()))) { 191658957c7SKonstantin Varlamov auto __xtmp = __x.base(); 192658957c7SKonstantin Varlamov auto __ytmp = __y.base(); 193658957c7SKonstantin Varlamov ranges::iter_swap(--__xtmp, --__ytmp); 194658957c7SKonstantin Varlamov } 195658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 196f32f3db9SLouis Dionne }; 197f32f3db9SLouis Dionne 19820a11cb5SNikolas Klauser template <class _Iter> 19920a11cb5SNikolas Klauser struct __is_reverse_iterator : false_type {}; 20020a11cb5SNikolas Klauser 20120a11cb5SNikolas Klauser template <class _Iter> 20220a11cb5SNikolas Klauser struct __is_reverse_iterator<reverse_iterator<_Iter> > : true_type {}; 20320a11cb5SNikolas Klauser 204f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 205f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 206f32f3db9SLouis Dionne bool 207f32f3db9SLouis Dionne operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 208658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 209658957c7SKonstantin Varlamov requires requires { 210658957c7SKonstantin Varlamov { __x.base() == __y.base() } -> convertible_to<bool>; 211658957c7SKonstantin Varlamov } 212658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 213f32f3db9SLouis Dionne { 214f32f3db9SLouis Dionne return __x.base() == __y.base(); 215f32f3db9SLouis Dionne } 216f32f3db9SLouis Dionne 217f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 218f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 219f32f3db9SLouis Dionne bool 220f32f3db9SLouis Dionne operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 221658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 222658957c7SKonstantin Varlamov requires requires { 223658957c7SKonstantin Varlamov { __x.base() > __y.base() } -> convertible_to<bool>; 224658957c7SKonstantin Varlamov } 225658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 226f32f3db9SLouis Dionne { 227f32f3db9SLouis Dionne return __x.base() > __y.base(); 228f32f3db9SLouis Dionne } 229f32f3db9SLouis Dionne 230f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 231f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 232f32f3db9SLouis Dionne bool 233f32f3db9SLouis Dionne operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 234658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 235658957c7SKonstantin Varlamov requires requires { 236658957c7SKonstantin Varlamov { __x.base() != __y.base() } -> convertible_to<bool>; 237658957c7SKonstantin Varlamov } 238658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 239f32f3db9SLouis Dionne { 240f32f3db9SLouis Dionne return __x.base() != __y.base(); 241f32f3db9SLouis Dionne } 242f32f3db9SLouis Dionne 243f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 244f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 245f32f3db9SLouis Dionne bool 246f32f3db9SLouis Dionne operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 247658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 248658957c7SKonstantin Varlamov requires requires { 249658957c7SKonstantin Varlamov { __x.base() < __y.base() } -> convertible_to<bool>; 250658957c7SKonstantin Varlamov } 251658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 252f32f3db9SLouis Dionne { 253f32f3db9SLouis Dionne return __x.base() < __y.base(); 254f32f3db9SLouis Dionne } 255f32f3db9SLouis Dionne 256f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 257f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 258f32f3db9SLouis Dionne bool 259f32f3db9SLouis Dionne operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 260658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 261658957c7SKonstantin Varlamov requires requires { 262658957c7SKonstantin Varlamov { __x.base() <= __y.base() } -> convertible_to<bool>; 263658957c7SKonstantin Varlamov } 264658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 265f32f3db9SLouis Dionne { 266f32f3db9SLouis Dionne return __x.base() <= __y.base(); 267f32f3db9SLouis Dionne } 268f32f3db9SLouis Dionne 269f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 270f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 271f32f3db9SLouis Dionne bool 272f32f3db9SLouis Dionne operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 273658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 274658957c7SKonstantin Varlamov requires requires { 275658957c7SKonstantin Varlamov { __x.base() >= __y.base() } -> convertible_to<bool>; 276658957c7SKonstantin Varlamov } 277658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 278f32f3db9SLouis Dionne { 279f32f3db9SLouis Dionne return __x.base() >= __y.base(); 280f32f3db9SLouis Dionne } 281f32f3db9SLouis Dionne 282d2baefaeSJoe Loser #if _LIBCPP_STD_VER > 17 283d8f3cdfeSMikhail Maltsev template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> 284d8f3cdfeSMikhail Maltsev _LIBCPP_HIDE_FROM_ABI constexpr 285d8f3cdfeSMikhail Maltsev compare_three_way_result_t<_Iter1, _Iter2> 286d8f3cdfeSMikhail Maltsev operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 287d8f3cdfeSMikhail Maltsev { 288d8f3cdfeSMikhail Maltsev return __y.base() <=> __x.base(); 289d8f3cdfeSMikhail Maltsev } 290d2baefaeSJoe Loser #endif // _LIBCPP_STD_VER > 17 291d8f3cdfeSMikhail Maltsev 292f32f3db9SLouis Dionne #ifndef _LIBCPP_CXX03_LANG 293f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 294f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 295f32f3db9SLouis Dionne auto 296f32f3db9SLouis Dionne operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 297f32f3db9SLouis Dionne -> decltype(__y.base() - __x.base()) 298f32f3db9SLouis Dionne { 299f32f3db9SLouis Dionne return __y.base() - __x.base(); 300f32f3db9SLouis Dionne } 301f32f3db9SLouis Dionne #else 302f32f3db9SLouis Dionne template <class _Iter1, class _Iter2> 303f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY 304f32f3db9SLouis Dionne typename reverse_iterator<_Iter1>::difference_type 305f32f3db9SLouis Dionne operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 306f32f3db9SLouis Dionne { 307f32f3db9SLouis Dionne return __y.base() - __x.base(); 308f32f3db9SLouis Dionne } 309f32f3db9SLouis Dionne #endif 310f32f3db9SLouis Dionne 311f32f3db9SLouis Dionne template <class _Iter> 312f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 313f32f3db9SLouis Dionne reverse_iterator<_Iter> 314f32f3db9SLouis Dionne operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) 315f32f3db9SLouis Dionne { 316f32f3db9SLouis Dionne return reverse_iterator<_Iter>(__x.base() - __n); 317f32f3db9SLouis Dionne } 318f32f3db9SLouis Dionne 319658957c7SKonstantin Varlamov #if _LIBCPP_STD_VER > 17 320658957c7SKonstantin Varlamov template <class _Iter1, class _Iter2> 321658957c7SKonstantin Varlamov requires (!sized_sentinel_for<_Iter1, _Iter2>) 322658957c7SKonstantin Varlamov inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true; 323658957c7SKonstantin Varlamov #endif // _LIBCPP_STD_VER > 17 324658957c7SKonstantin Varlamov 325f32f3db9SLouis Dionne #if _LIBCPP_STD_VER > 11 326f32f3db9SLouis Dionne template <class _Iter> 327f32f3db9SLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 328f32f3db9SLouis Dionne reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) 329f32f3db9SLouis Dionne { 330f32f3db9SLouis Dionne return reverse_iterator<_Iter>(__i); 331f32f3db9SLouis Dionne } 332f32f3db9SLouis Dionne #endif 333f32f3db9SLouis Dionne 33420a11cb5SNikolas Klauser #if _LIBCPP_STD_VER <= 17 335fb3477a4SNikolas Klauser template <class _Iter> 33620a11cb5SNikolas Klauser using __unconstrained_reverse_iterator = reverse_iterator<_Iter>; 33720a11cb5SNikolas Klauser #else 338fb3477a4SNikolas Klauser 33920a11cb5SNikolas Klauser // __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working 34020a11cb5SNikolas Klauser // around a language issue in C++20. 34120a11cb5SNikolas Klauser // In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will 34220a11cb5SNikolas Klauser // result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not 34320a11cb5SNikolas Klauser // an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a 34420a11cb5SNikolas Klauser // C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with 34520a11cb5SNikolas Klauser // tweaks to make it support hostile iterators. 34620a11cb5SNikolas Klauser // 34720a11cb5SNikolas Klauser // A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match 34820a11cb5SNikolas Klauser // and the other requires an implicit conversion, for example: 34920a11cb5SNikolas Klauser // friend bool operator==(const BaseIter&, const DerivedIter&); 35020a11cb5SNikolas Klauser // 35120a11cb5SNikolas Klauser // C++20 rules for rewriting equality operators create another overload of this function with parameters reversed: 35220a11cb5SNikolas Klauser // friend bool operator==(const DerivedIter&, const BaseIter&); 35320a11cb5SNikolas Klauser // 35420a11cb5SNikolas Klauser // This creates an ambiguity in overload resolution. 35520a11cb5SNikolas Klauser // 35620a11cb5SNikolas Klauser // Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function 35720a11cb5SNikolas Klauser // body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however, 35820a11cb5SNikolas Klauser // it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its 35920a11cb5SNikolas Klauser // base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload 36020a11cb5SNikolas Klauser // resolution. This class simply removes the problematic constraints from comparison functions. 36120a11cb5SNikolas Klauser template <class _Iter> 36220a11cb5SNikolas Klauser class __unconstrained_reverse_iterator { 36320a11cb5SNikolas Klauser _Iter __iter_; 364fb3477a4SNikolas Klauser 36520a11cb5SNikolas Klauser public: 366*33e5f159SKonstantin Varlamov static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>); 36720a11cb5SNikolas Klauser 36820a11cb5SNikolas Klauser using iterator_type = _Iter; 36920a11cb5SNikolas Klauser using iterator_category = 37020a11cb5SNikolas Klauser _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; 37120a11cb5SNikolas Klauser using pointer = __iterator_pointer_type<_Iter>; 37220a11cb5SNikolas Klauser using value_type = iter_value_t<_Iter>; 37320a11cb5SNikolas Klauser using difference_type = iter_difference_t<_Iter>; 37420a11cb5SNikolas Klauser using reference = iter_reference_t<_Iter>; 37520a11cb5SNikolas Klauser 37620a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default; 37720a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default; 37820a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {} 37920a11cb5SNikolas Klauser 38020a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() const { return __iter_; } 38120a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { 38220a11cb5SNikolas Klauser auto __tmp = __iter_; 38320a11cb5SNikolas Klauser return *--__tmp; 384fb3477a4SNikolas Klauser } 385fb3477a4SNikolas Klauser 38620a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { 38720a11cb5SNikolas Klauser if constexpr (is_pointer_v<_Iter>) { 38820a11cb5SNikolas Klauser return std::prev(__iter_); 38920a11cb5SNikolas Klauser } else { 39020a11cb5SNikolas Klauser return std::prev(__iter_).operator->(); 39120a11cb5SNikolas Klauser } 39220a11cb5SNikolas Klauser } 39320a11cb5SNikolas Klauser 394*33e5f159SKonstantin Varlamov _LIBCPP_HIDE_FROM_ABI friend constexpr 395*33e5f159SKonstantin Varlamov iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i) 396*33e5f159SKonstantin Varlamov noexcept(is_nothrow_copy_constructible_v<_Iter> && 397*33e5f159SKonstantin Varlamov noexcept(ranges::iter_move(--declval<_Iter&>()))) { 398*33e5f159SKonstantin Varlamov auto __tmp = __i.base(); 399*33e5f159SKonstantin Varlamov return ranges::iter_move(--__tmp); 400*33e5f159SKonstantin Varlamov } 401*33e5f159SKonstantin Varlamov 40220a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() { 40320a11cb5SNikolas Klauser --__iter_; 40420a11cb5SNikolas Klauser return *this; 40520a11cb5SNikolas Klauser } 40620a11cb5SNikolas Klauser 40720a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator++(int) { 40820a11cb5SNikolas Klauser auto __tmp = *this; 40920a11cb5SNikolas Klauser --__iter_; 41020a11cb5SNikolas Klauser return __tmp; 41120a11cb5SNikolas Klauser } 41220a11cb5SNikolas Klauser 41320a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator--() { 41420a11cb5SNikolas Klauser ++__iter_; 41520a11cb5SNikolas Klauser return *this; 41620a11cb5SNikolas Klauser } 41720a11cb5SNikolas Klauser 41820a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator--(int) { 41920a11cb5SNikolas Klauser auto __tmp = *this; 42020a11cb5SNikolas Klauser ++__iter_; 42120a11cb5SNikolas Klauser return __tmp; 42220a11cb5SNikolas Klauser } 42320a11cb5SNikolas Klauser 42420a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator+=(difference_type __n) { 42520a11cb5SNikolas Klauser __iter_ -= __n; 42620a11cb5SNikolas Klauser return *this; 42720a11cb5SNikolas Klauser } 42820a11cb5SNikolas Klauser 42920a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator-=(difference_type __n) { 43020a11cb5SNikolas Klauser __iter_ += __n; 43120a11cb5SNikolas Klauser return *this; 43220a11cb5SNikolas Klauser } 43320a11cb5SNikolas Klauser 43420a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator+(difference_type __n) const { 43520a11cb5SNikolas Klauser return __unconstrained_reverse_iterator(__iter_ - __n); 43620a11cb5SNikolas Klauser } 43720a11cb5SNikolas Klauser 43820a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator-(difference_type __n) const { 43920a11cb5SNikolas Klauser return __unconstrained_reverse_iterator(__iter_ + __n); 44020a11cb5SNikolas Klauser } 44120a11cb5SNikolas Klauser 44220a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr difference_type operator-(const __unconstrained_reverse_iterator& __other) const { 44320a11cb5SNikolas Klauser return __other.__iter_ - __iter_; 44420a11cb5SNikolas Klauser } 44520a11cb5SNikolas Klauser 44620a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const { return *(*this + __n); } 44720a11cb5SNikolas Klauser 44820a11cb5SNikolas Klauser // Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the 44920a11cb5SNikolas Klauser // rationale. 45020a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI friend constexpr bool 45120a11cb5SNikolas Klauser operator==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 45220a11cb5SNikolas Klauser return __lhs.base() == __rhs.base(); 45320a11cb5SNikolas Klauser } 45420a11cb5SNikolas Klauser 45520a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI friend constexpr bool 45620a11cb5SNikolas Klauser operator!=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 45720a11cb5SNikolas Klauser return __lhs.base() != __rhs.base(); 45820a11cb5SNikolas Klauser } 45920a11cb5SNikolas Klauser 46020a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI friend constexpr bool 46120a11cb5SNikolas Klauser operator<(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 46220a11cb5SNikolas Klauser return __lhs.base() > __rhs.base(); 46320a11cb5SNikolas Klauser } 46420a11cb5SNikolas Klauser 46520a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI friend constexpr bool 46620a11cb5SNikolas Klauser operator>(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 46720a11cb5SNikolas Klauser return __lhs.base() < __rhs.base(); 46820a11cb5SNikolas Klauser } 46920a11cb5SNikolas Klauser 47020a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI friend constexpr bool 47120a11cb5SNikolas Klauser operator<=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 47220a11cb5SNikolas Klauser return __lhs.base() >= __rhs.base(); 47320a11cb5SNikolas Klauser } 47420a11cb5SNikolas Klauser 47520a11cb5SNikolas Klauser _LIBCPP_HIDE_FROM_ABI friend constexpr bool 47620a11cb5SNikolas Klauser operator>=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 47720a11cb5SNikolas Klauser return __lhs.base() <= __rhs.base(); 47820a11cb5SNikolas Klauser } 47920a11cb5SNikolas Klauser }; 48020a11cb5SNikolas Klauser 48120a11cb5SNikolas Klauser template <class _Iter> 48220a11cb5SNikolas Klauser struct __is_reverse_iterator<__unconstrained_reverse_iterator<_Iter>> : true_type {}; 48320a11cb5SNikolas Klauser 48420a11cb5SNikolas Klauser #endif // _LIBCPP_STD_VER <= 17 48520a11cb5SNikolas Klauser 48620a11cb5SNikolas Klauser template <template <class> class _RevIter1, template <class> class _RevIter2, class _Iter> 48720a11cb5SNikolas Klauser struct __unwrap_reverse_iter_impl { 48820a11cb5SNikolas Klauser using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>())); 48920a11cb5SNikolas Klauser using _ReverseWrapper = _RevIter1<_RevIter2<_Iter> >; 49020a11cb5SNikolas Klauser 49120a11cb5SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper 49220a11cb5SNikolas Klauser __rewrap(_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) { 49320a11cb5SNikolas Klauser return _ReverseWrapper( 49420a11cb5SNikolas Klauser _RevIter2<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap(__orig_iter.base().base(), __unwrapped_iter))); 49520a11cb5SNikolas Klauser } 49620a11cb5SNikolas Klauser 49720a11cb5SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _UnwrappedIter __unwrap(_ReverseWrapper __i) _NOEXCEPT { 4980a92e072SNikolas Klauser return __unwrap_iter_impl<_Iter>::__unwrap(__i.base().base()); 499fb3477a4SNikolas Klauser } 500fb3477a4SNikolas Klauser }; 501fb3477a4SNikolas Klauser 5027d426a39SNikolas Klauser #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 5037d426a39SNikolas Klauser template <ranges::bidirectional_range _Range> 5047d426a39SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr ranges:: 5057d426a39SNikolas Klauser subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>> 5067d426a39SNikolas Klauser __reverse_range(_Range&& __range) { 5077d426a39SNikolas Klauser auto __first = ranges::begin(__range); 5087d426a39SNikolas Klauser return {std::make_reverse_iterator(ranges::next(__first, ranges::end(__range))), std::make_reverse_iterator(__first)}; 5097d426a39SNikolas Klauser } 5107d426a39SNikolas Klauser #endif 5117d426a39SNikolas Klauser 51220a11cb5SNikolas Klauser template <class _Iter, bool __b> 51320a11cb5SNikolas Klauser struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b> 51420a11cb5SNikolas Klauser : __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {}; 51520a11cb5SNikolas Klauser 51620a11cb5SNikolas Klauser #if _LIBCPP_STD_VER > 17 51720a11cb5SNikolas Klauser 51820a11cb5SNikolas Klauser template <class _Iter, bool __b> 51920a11cb5SNikolas Klauser struct __unwrap_iter_impl<reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b> 52020a11cb5SNikolas Klauser : __unwrap_reverse_iter_impl<reverse_iterator, __unconstrained_reverse_iterator, _Iter> {}; 52120a11cb5SNikolas Klauser 52220a11cb5SNikolas Klauser template <class _Iter, bool __b> 52320a11cb5SNikolas Klauser struct __unwrap_iter_impl<__unconstrained_reverse_iterator<reverse_iterator<_Iter>>, __b> 52420a11cb5SNikolas Klauser : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, reverse_iterator, _Iter> {}; 52520a11cb5SNikolas Klauser 52620a11cb5SNikolas Klauser template <class _Iter, bool __b> 52720a11cb5SNikolas Klauser struct __unwrap_iter_impl<__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b> 52820a11cb5SNikolas Klauser : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {}; 52920a11cb5SNikolas Klauser 53020a11cb5SNikolas Klauser #endif // _LIBCPP_STD_VER > 17 53120a11cb5SNikolas Klauser 532f32f3db9SLouis Dionne _LIBCPP_END_NAMESPACE_STD 533f32f3db9SLouis Dionne 534f32f3db9SLouis Dionne #endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 535