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_HPP
0015 #define RANGES_V3_VIEW_DROP_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/algorithm/min.hpp>
0024 #include <range/v3/functional/bind_back.hpp>
0025 #include <range/v3/iterator/operations.hpp>
0026 #include <range/v3/iterator/traits.hpp>
0027 #include <range/v3/range/concepts.hpp>
0028 #include <range/v3/range/traits.hpp>
0029 #include <range/v3/utility/box.hpp>
0030 #include <range/v3/utility/optional.hpp>
0031 #include <range/v3/utility/static_const.hpp>
0032 #include <range/v3/view/all.hpp>
0033 #include <range/v3/view/interface.hpp>
0034 #include <range/v3/view/subrange.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 drop_view
0045       : view_interface<drop_view<Rng>,
0046                        is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
0047       , private detail::non_propagating_cache<iterator_t<Rng>, drop_view<Rng>,
0048                                               !random_access_range<Rng>>
0049     {
0050     private:
0051         using difference_type_ = range_difference_t<Rng>;
0052         Rng rng_;
0053         difference_type_ n_;
0054 
0055         template(bool Const = true)(
0056             requires Const AND range<meta::const_if_c<Const, Rng>>)
0057         iterator_t<meta::const_if_c<Const, Rng>> //
0058         get_begin_(std::true_type, std::true_type) const
0059         {
0060             CPP_assert(random_access_range<meta::const_if_c<Const, Rng>>);
0061             return next(ranges::begin(rng_), n_, ranges::end(rng_));
0062         }
0063         iterator_t<Rng> get_begin_(std::true_type, std::false_type)
0064         {
0065             CPP_assert(random_access_range<Rng>);
0066             return next(ranges::begin(rng_), n_, ranges::end(rng_));
0067         }
0068         iterator_t<Rng> get_begin_(std::false_type, detail::ignore_t)
0069         {
0070             CPP_assert(!random_access_range<Rng>);
0071             using cache_t =
0072                 detail::non_propagating_cache<iterator_t<Rng>, drop_view<Rng>>;
0073             auto & begin_ = static_cast<cache_t &>(*this);
0074             if(!begin_)
0075                 begin_ = next(ranges::begin(rng_), n_, ranges::end(rng_));
0076             return *begin_;
0077         }
0078 
0079     public:
0080         drop_view() = default;
0081         drop_view(Rng rng, difference_type_ n)
0082           : rng_(std::move(rng))
0083           , n_(n)
0084         {
0085             RANGES_EXPECT(n >= 0);
0086         }
0087         iterator_t<Rng> begin()
0088         {
0089             return this->get_begin_(meta::bool_<random_access_range<Rng>>{},
0090                                     std::false_type{});
0091         }
0092         sentinel_t<Rng> end()
0093         {
0094             return ranges::end(rng_);
0095         }
0096         template(bool Const = true)(
0097             requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
0098         iterator_t<meta::const_if_c<Const, Rng>> begin() const
0099         {
0100             return this->get_begin_(std::true_type{}, std::true_type{});
0101         }
0102         template(bool Const = true)(
0103             requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
0104         sentinel_t<meta::const_if_c<Const, Rng>> end() const
0105         {
0106             return ranges::end(rng_);
0107         }
0108         CPP_auto_member
0109         auto CPP_fun(size)()(const //
0110             requires sized_range<Rng const>)
0111         {
0112             auto const s = ranges::size(rng_);
0113             auto const n = static_cast<range_size_t<Rng const>>(n_);
0114             return s < n ? 0 : s - n;
0115         }
0116         CPP_auto_member
0117         auto CPP_fun(size)()(
0118             requires sized_range<Rng>)
0119         {
0120             auto const s = ranges::size(rng_);
0121             auto const n = static_cast<range_size_t<Rng>>(n_);
0122             return s < n ? 0 : s - n;
0123         }
0124         Rng base() const
0125         {
0126             return rng_;
0127         }
0128     };
0129 
0130     template<typename Rng>
0131     RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_view<Rng>> = //
0132         enable_borrowed_range<Rng>;
0133 
0134 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0135     template<typename Rng>
0136     drop_view(Rng &&, range_difference_t<Rng>)
0137         -> drop_view<views::all_t<Rng>>;
0138 #endif
0139 
0140     namespace views
0141     {
0142         struct drop_base_fn
0143         {
0144         private:
0145             template<typename Rng>
0146             static auto impl_(Rng && rng, range_difference_t<Rng> n, input_range_tag)
0147                 -> drop_view<all_t<Rng>>
0148             {
0149                 return {all(static_cast<Rng &&>(rng)), n};
0150             }
0151             template(typename Rng)(
0152                 requires borrowed_range<Rng> AND sized_range<Rng>)
0153             static subrange<iterator_t<Rng>, sentinel_t<Rng>> //
0154             impl_(Rng && rng, range_difference_t<Rng> n, random_access_range_tag)
0155             {
0156                 return {begin(rng) + ranges::min(n, distance(rng)), end(rng)};
0157             }
0158 
0159         public:
0160             template(typename Rng)(
0161                 requires viewable_range<Rng> AND input_range<Rng>)
0162             auto operator()(Rng && rng, range_difference_t<Rng> n) const
0163             {
0164                 return drop_base_fn::impl_(
0165                     static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
0166             }
0167         };
0168 
0169         struct drop_fn : drop_base_fn
0170         {
0171             using drop_base_fn::operator();
0172 
0173             template(typename Int)(
0174                 requires detail::integer_like_<Int>)
0175             constexpr auto operator()(Int n) const
0176             {
0177                 return make_view_closure(bind_back(drop_base_fn{}, n));
0178             }
0179         };
0180 
0181         /// \relates drop_fn
0182         /// \ingroup group-views
0183         RANGES_INLINE_VARIABLE(drop_fn, drop)
0184     } // namespace views
0185 
0186     namespace cpp20
0187     {
0188         namespace views
0189         {
0190             using ranges::views::drop;
0191         }
0192         template(typename Rng)(
0193             requires view_<Rng>)
0194             using drop_view = ranges::drop_view<Rng>;
0195     } // namespace cpp20
0196     /// @}
0197 } // namespace ranges
0198 
0199 #include <range/v3/detail/epilogue.hpp>
0200 #include <range/v3/detail/satisfy_boost_range.hpp>
0201 RANGES_SATISFY_BOOST_RANGE(::ranges::drop_view)
0202 
0203 #endif