/// \file // Range v3 library // // Copyright Eric Niebler 2014-present // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP #define RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP #include #include #include #include #include namespace ranges { /// \addtogroup group-iterator /// @{ /// \cond namespace detail { template struct reverse_cursor { private: CPP_assert(bidirectional_iterator); friend range_access; template friend struct reverse_cursor; struct mixin : basic_mixin { mixin() = default; #ifndef _MSC_VER using basic_mixin::basic_mixin; #else constexpr explicit mixin(reverse_cursor && cur) : basic_mixin(static_cast(cur)) {} constexpr explicit mixin(reverse_cursor const & cur) : basic_mixin(cur) {} #endif constexpr mixin(I it) : mixin{reverse_cursor{it}} {} constexpr I base() const { return this->get().base(); } }; I it_; constexpr reverse_cursor(I it) : it_(std::move(it)) {} constexpr iter_reference_t read() const { return *arrow(); } constexpr I arrow() const { auto tmp = it_; --tmp; return tmp; } constexpr I base() const { return it_; } template(typename J)( /// \pre requires sentinel_for) constexpr bool equal(reverse_cursor const & that) const { return it_ == that.it_; } constexpr void next() { --it_; } constexpr void prev() { ++it_; } CPP_member constexpr auto advance(iter_difference_t n) // -> CPP_ret(void)( /// \pre requires random_access_iterator) { it_ -= n; } template(typename J)( /// \pre requires sized_sentinel_for) constexpr iter_difference_t distance_to(reverse_cursor const & that) // const { return it_ - that.base(); } constexpr iter_rvalue_reference_t move() const noexcept(noexcept((void)I(I(it_)), (void)--const_cast(it_), iter_move(it_))) { auto tmp = it_; --tmp; return iter_move(tmp); } public: reverse_cursor() = default; template(typename U)( /// \pre requires convertible_to) constexpr reverse_cursor(reverse_cursor const & u) : it_(u.base()) {} }; } // namespace detail /// \endcond struct make_reverse_iterator_fn { template(typename I)( /// \pre requires bidirectional_iterator) constexpr reverse_iterator operator()(I i) const { return reverse_iterator(i); } }; RANGES_INLINE_VARIABLE(make_reverse_iterator_fn, make_reverse_iterator) namespace cpp20 { using ranges::make_reverse_iterator; using ranges::reverse_iterator; } // namespace cpp20 /// @} } // namespace ranges #include #endif // RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP