Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-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_DROP_EXACTLY_HPP
0015 #define RANGES_V3_VIEW_DROP_EXACTLY_HPP
0016 
0017 #include <type_traits>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <range/v3/range_fwd.hpp>
0022 
0023 #include <range/v3/functional/bind_back.hpp>
0024 #include <range/v3/iterator/operations.hpp>
0025 #include <range/v3/iterator/traits.hpp>
0026 #include <range/v3/range/concepts.hpp>
0027 #include <range/v3/range/traits.hpp>
0028 #include <range/v3/utility/box.hpp>
0029 #include <range/v3/utility/optional.hpp>
0030 #include <range/v3/utility/static_const.hpp>
0031 #include <range/v3/view/all.hpp>
0032 #include <range/v3/view/interface.hpp>
0033 #include <range/v3/view/subrange.hpp>
0034 #include <range/v3/view/view.hpp>
0035 
0036 #include <range/v3/detail/prologue.hpp>
0037 
0038 namespace ranges
0039 {
0040     /// \addtogroup group-views
0041     /// @{
0042     template<typename Rng>
0043     struct RANGES_EMPTY_BASES drop_exactly_view
0044       : view_interface<drop_exactly_view<Rng>,
0045                        is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0046       , private detail::non_propagating_cache<iterator_t<Rng>, drop_exactly_view<Rng>,
0047                                               !random_access_range<Rng>>
0048     {
0049     private:
0050         using difference_type_ = range_difference_t<Rng>;
0051         Rng rng_;
0052         difference_type_ n_;
0053 
0054         // random_access_range == true
0055         template(bool Const = true)(
0056             requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
0057         iterator_t<meta::const_if_c<Const, Rng>> get_begin_(std::true_type) const
0058         {
0059             return next(ranges::begin(rng_), n_);
0060         }
0061         iterator_t<Rng> get_begin_(std::true_type)
0062         {
0063             return next(ranges::begin(rng_), n_);
0064         }
0065         // random_access_range == false
0066         iterator_t<Rng> get_begin_(std::false_type)
0067         {
0068             using cache_t =
0069                 detail::non_propagating_cache<iterator_t<Rng>, drop_exactly_view<Rng>>;
0070             auto & begin_ = static_cast<cache_t &>(*this);
0071             if(!begin_)
0072                 begin_ = next(ranges::begin(rng_), n_);
0073             return *begin_;
0074         }
0075 
0076     public:
0077         drop_exactly_view() = default;
0078         drop_exactly_view(Rng rng, difference_type_ n)
0079           : rng_(std::move(rng))
0080           , n_(n)
0081         {
0082             RANGES_EXPECT(n >= 0);
0083         }
0084         iterator_t<Rng> begin()
0085         {
0086             return this->get_begin_(meta::bool_<random_access_range<Rng>>{});
0087         }
0088         sentinel_t<Rng> end()
0089         {
0090             return ranges::end(rng_);
0091         }
0092         template(bool Const = true)(
0093             requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
0094         iterator_t<meta::const_if_c<Const, Rng>> begin() const
0095         {
0096             return this->get_begin_(std::true_type{});
0097         }
0098         template(bool Const = true)(
0099             requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
0100         sentinel_t<meta::const_if_c<Const, Rng>> end() const
0101         {
0102             return ranges::end(rng_);
0103         }
0104         CPP_auto_member
0105         auto CPP_fun(size)()(const
0106             requires sized_range<Rng const>)
0107         {
0108             return ranges::size(rng_) - static_cast<range_size_t<Rng const>>(n_);
0109         }
0110         CPP_auto_member
0111         auto CPP_fun(size)()(
0112             requires sized_range<Rng>)
0113         {
0114             return ranges::size(rng_) - static_cast<range_size_t<Rng>>(n_);
0115         }
0116         Rng base() const
0117         {
0118             return rng_;
0119         }
0120     };
0121 
0122     template<typename Rng>
0123     RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_exactly_view<Rng>> = //
0124         enable_borrowed_range<Rng>;
0125 
0126 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0127     template<typename Rng>
0128     drop_exactly_view(Rng &&, range_difference_t<Rng>)
0129         ->drop_exactly_view<views::all_t<Rng>>;
0130 #endif
0131 
0132     namespace views
0133     {
0134         struct drop_exactly_base_fn
0135         {
0136         private:
0137             template<typename Rng>
0138             static auto impl_(Rng && rng, range_difference_t<Rng> n, input_range_tag)
0139                 -> drop_exactly_view<all_t<Rng>>
0140             {
0141                 return {all(static_cast<Rng &&>(rng)), n};
0142             }
0143             template(typename Rng)(
0144                 requires borrowed_range<Rng>)
0145             static subrange<iterator_t<Rng>, sentinel_t<Rng>> //
0146             impl_(Rng && rng, range_difference_t<Rng> n, random_access_range_tag)
0147             {
0148                 return {begin(rng) + n, end(rng)};
0149             }
0150 
0151         public:
0152             template(typename Rng)(
0153                 requires viewable_range<Rng> AND input_range<Rng>)
0154             auto operator()(Rng && rng, range_difference_t<Rng> n) const
0155             {
0156                 return drop_exactly_base_fn::impl_(
0157                     static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
0158             }
0159         };
0160 
0161         struct drop_exactly_fn : drop_exactly_base_fn
0162         {
0163             using drop_exactly_base_fn::operator();
0164 
0165             template(typename Int)(
0166                 requires detail::integer_like_<Int>)
0167             constexpr auto operator()(Int n) const
0168             {
0169                 return make_view_closure(bind_back(drop_exactly_base_fn{}, n));
0170             }
0171         };
0172 
0173         /// \relates drop_exactly_fn
0174         /// \ingroup group-views
0175         RANGES_INLINE_VARIABLE(drop_exactly_fn, drop_exactly)
0176     } // namespace views
0177     /// @}
0178 } // namespace ranges
0179 
0180 #include <range/v3/detail/epilogue.hpp>
0181 #include <range/v3/detail/satisfy_boost_range.hpp>
0182 RANGES_SATISFY_BOOST_RANGE(::ranges::drop_exactly_view)
0183 
0184 #endif