File indexing completed on 2025-01-18 10:09:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP
0014 #define RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP
0015
0016 #include <utility>
0017
0018 #include <range/v3/range_fwd.hpp>
0019
0020 #include <range/v3/iterator/basic_iterator.hpp>
0021 #include <range/v3/iterator/concepts.hpp>
0022
0023 #include <range/v3/detail/prologue.hpp>
0024
0025 namespace ranges
0026 {
0027
0028
0029
0030
0031 namespace detail
0032 {
0033 template<typename I>
0034 struct reverse_cursor
0035 {
0036 private:
0037 CPP_assert(bidirectional_iterator<I>);
0038 friend range_access;
0039
0040 using value_type = iter_value_t<I>;
0041
0042 template<typename OtherI>
0043 friend struct reverse_cursor;
0044 struct mixin : basic_mixin<reverse_cursor>
0045 {
0046 mixin() = default;
0047 #ifndef _MSC_VER
0048 using basic_mixin<reverse_cursor>::basic_mixin;
0049 #else
0050 constexpr explicit mixin(reverse_cursor && cur)
0051 : basic_mixin<reverse_cursor>(static_cast<reverse_cursor &&>(cur))
0052 {}
0053 constexpr explicit mixin(reverse_cursor const & cur)
0054 : basic_mixin<reverse_cursor>(cur)
0055 {}
0056 #endif
0057 constexpr mixin(I it)
0058 : mixin{reverse_cursor{it}}
0059 {}
0060 constexpr I base() const
0061 {
0062 return this->get().base();
0063 }
0064 };
0065
0066 I it_;
0067
0068 constexpr reverse_cursor(I it)
0069 : it_(std::move(it))
0070 {}
0071 constexpr iter_reference_t<I> read() const
0072 {
0073 return *arrow();
0074 }
0075 constexpr I arrow() const
0076 {
0077 auto tmp = it_;
0078 --tmp;
0079 return tmp;
0080 }
0081 constexpr I base() const
0082 {
0083 return it_;
0084 }
0085 template(typename J)(
0086 requires sentinel_for<J, I>)
0087 constexpr bool equal(reverse_cursor<J> const & that) const
0088 {
0089 return it_ == that.it_;
0090 }
0091 constexpr void next()
0092 {
0093 --it_;
0094 }
0095 constexpr void prev()
0096 {
0097 ++it_;
0098 }
0099 CPP_member
0100 constexpr auto advance(iter_difference_t<I> n)
0101 -> CPP_ret(void)(
0102 requires random_access_iterator<I>)
0103 {
0104 it_ -= n;
0105 }
0106 template(typename J)(
0107 requires sized_sentinel_for<J, I>)
0108 constexpr iter_difference_t<I> distance_to(reverse_cursor<J> const & that)
0109 const
0110 {
0111 return it_ - that.base();
0112 }
0113 constexpr iter_rvalue_reference_t<I> move() const
0114 noexcept(noexcept((void)I(I(it_)), (void)--const_cast<I &>(it_),
0115 iter_move(it_)))
0116 {
0117 auto tmp = it_;
0118 --tmp;
0119 return iter_move(tmp);
0120 }
0121
0122 public:
0123 reverse_cursor() = default;
0124 template(typename U)(
0125 requires convertible_to<U, I>)
0126 constexpr reverse_cursor(reverse_cursor<U> const & u)
0127 : it_(u.base())
0128 {}
0129 };
0130 }
0131
0132
0133 struct make_reverse_iterator_fn
0134 {
0135 template(typename I)(
0136 requires bidirectional_iterator<I>)
0137 constexpr reverse_iterator<I> operator()(I i) const
0138 {
0139 return reverse_iterator<I>(i);
0140 }
0141 };
0142
0143 RANGES_INLINE_VARIABLE(make_reverse_iterator_fn, make_reverse_iterator)
0144
0145 namespace cpp20
0146 {
0147 using ranges::make_reverse_iterator;
0148 using ranges::reverse_iterator;
0149 }
0150
0151 }
0152
0153 #include <range/v3/detail/epilogue.hpp>
0154
0155 #endif