Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:50

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
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     /// \addtogroup group-iterator
0028     /// @{
0029 
0030     /// \cond
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     } // namespace detail
0131     /// \endcond
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     } // namespace cpp20
0150     /// @}
0151 } // namespace ranges
0152 
0153 #include <range/v3/detail/epilogue.hpp>
0154 
0155 #endif // RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP