Back to home page

EIC code displayed by LXR

 
 

    


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

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 
0014 #ifndef RANGES_V3_VIEW_REVERSE_HPP
0015 #define RANGES_V3_VIEW_REVERSE_HPP
0016 
0017 #include <iterator>
0018 #include <utility>
0019 
0020 #include <meta/meta.hpp>
0021 
0022 #include <range/v3/range_fwd.hpp>
0023 
0024 #include <range/v3/iterator/operations.hpp>
0025 #include <range/v3/iterator/reverse_iterator.hpp>
0026 #include <range/v3/range/access.hpp>
0027 #include <range/v3/range/primitives.hpp>
0028 #include <range/v3/range/traits.hpp>
0029 #include <range/v3/utility/box.hpp>
0030 #include <range/v3/utility/get.hpp>
0031 #include <range/v3/utility/optional.hpp>
0032 #include <range/v3/utility/static_const.hpp>
0033 #include <range/v3/view/adaptor.hpp>
0034 #include <range/v3/view/all.hpp>
0035 #include <range/v3/view/view.hpp>
0036 
0037 #include <range/v3/detail/prologue.hpp>
0038 
0039 namespace ranges
0040 {
0041     /// \addtogroup group-views
0042     /// @{
0043     template<typename Rng>
0044     struct RANGES_EMPTY_BASES reverse_view
0045       : view_interface<reverse_view<Rng>, range_cardinality<Rng>::value>
0046       , private detail::non_propagating_cache<iterator_t<Rng>, reverse_view<Rng>,
0047                                               !common_range<Rng>>
0048     {
0049     private:
0050         CPP_assert(bidirectional_range<Rng>);
0051         Rng rng_;
0052         constexpr reverse_iterator<iterator_t<Rng>> begin_(std::true_type)
0053         {
0054             return make_reverse_iterator(ranges::end(rng_));
0055         }
0056         constexpr reverse_iterator<iterator_t<Rng>> begin_(std::false_type)
0057         {
0058             using cache_t =
0059                 detail::non_propagating_cache<iterator_t<Rng>, reverse_view<Rng>>;
0060             auto & end_ = static_cast<cache_t &>(*this);
0061             if(!end_)
0062             {
0063 #if defined(_MSC_VER)
0064                 auto tmp = ranges::begin(rng_);
0065                 auto e = ranges::end(rng_);
0066                 while(tmp != e)
0067                     ++tmp;
0068 #else
0069                 auto tmp = ranges::next(ranges::begin(rng_), ranges::end(rng_));
0070 #endif
0071                 end_ = std::move(tmp);
0072             }
0073             return make_reverse_iterator(*end_);
0074         }
0075 
0076     public:
0077         reverse_view() = default;
0078         constexpr explicit reverse_view(Rng rng)
0079           : rng_(detail::move(rng))
0080         {}
0081         Rng base() const
0082         {
0083             return rng_;
0084         }
0085         constexpr reverse_iterator<iterator_t<Rng>> begin()
0086         {
0087             return begin_(meta::bool_<(bool)common_range<Rng>>{});
0088         }
0089         template(bool Const = true)(
0090             requires Const AND common_range<meta::const_if_c<Const, Rng>>)
0091         constexpr reverse_iterator<iterator_t<meta::const_if_c<Const, Rng>>> begin() const
0092         {
0093             return make_reverse_iterator(ranges::end(rng_));
0094         }
0095         constexpr reverse_iterator<iterator_t<Rng>> end()
0096         {
0097             return make_reverse_iterator(ranges::begin(rng_));
0098         }
0099         template(bool Const = true)(
0100             requires Const AND common_range<meta::const_if_c<Const, Rng>>)
0101         constexpr reverse_iterator<iterator_t<meta::const_if_c<Const, Rng>>> end() const
0102         {
0103             return make_reverse_iterator(ranges::begin(rng_));
0104         }
0105         CPP_auto_member
0106         constexpr auto CPP_fun(size)()(
0107             requires sized_range<Rng>)
0108         {
0109             return ranges::size(rng_);
0110         }
0111         CPP_auto_member
0112         constexpr auto CPP_fun(size)()(const //
0113             requires sized_range<Rng const>)
0114         {
0115             return ranges::size(rng_);
0116         }
0117     };
0118 
0119     template<typename Rng>
0120     struct reverse_view<reverse_view<Rng>> : Rng
0121     {
0122         CPP_assert(bidirectional_range<Rng>);
0123         CPP_assert(
0124             same_as<detail::decay_t<decltype(std::declval<reverse_view<Rng>>().base())>,
0125                     Rng>);
0126 
0127         reverse_view() = default;
0128         constexpr explicit reverse_view(reverse_view<Rng> rng)
0129           : Rng(rng.base())
0130         {}
0131 
0132         constexpr reverse_view<Rng> base() const
0133         {
0134             return reverse_view<Rng>{*this};
0135         }
0136     };
0137 
0138     template<typename Rng>
0139     RANGES_INLINE_VAR constexpr bool enable_borrowed_range<reverse_view<Rng>> =
0140         enable_borrowed_range<Rng>;
0141 
0142 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0143     template<typename Rng>
0144     reverse_view(Rng &&) //
0145         -> reverse_view<views::all_t<Rng>>;
0146 
0147     template<typename Rng>
0148     reverse_view(reverse_view<Rng>)
0149         -> reverse_view<reverse_view<Rng>>;
0150 #endif
0151 
0152     namespace views
0153     {
0154         struct reverse_fn
0155         {
0156             template(typename Rng)(
0157                 requires viewable_range<Rng> AND bidirectional_range<Rng>)
0158             constexpr reverse_view<all_t<Rng>> operator()(Rng && rng) const
0159             {
0160                 return reverse_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
0161             }
0162         };
0163 
0164         /// \relates reverse_fn
0165         /// \ingroup group-views
0166         RANGES_INLINE_VARIABLE(view_closure<reverse_fn>, reverse)
0167     } // namespace views
0168 
0169     namespace cpp20
0170     {
0171         namespace views
0172         {
0173             using ranges::views::reverse;
0174         }
0175         template(typename Rng)(
0176             requires view_<Rng> AND bidirectional_range<Rng>)
0177         using reverse_view = ranges::reverse_view<Rng>;
0178     } // namespace cpp20
0179     /// @}
0180 } // namespace ranges
0181 
0182 #include <range/v3/detail/epilogue.hpp>
0183 #include <range/v3/detail/satisfy_boost_range.hpp>
0184 RANGES_SATISFY_BOOST_RANGE(::ranges::reverse_view)
0185 
0186 #endif