Back to home page

EIC code displayed by LXR

 
 

    


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

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_ACTION_SLICE_HPP
0015 #define RANGES_V3_ACTION_SLICE_HPP
0016 
0017 #include <meta/meta.hpp>
0018 
0019 #include <range/v3/range_fwd.hpp>
0020 
0021 #include <range/v3/action/action.hpp>
0022 #include <range/v3/action/erase.hpp>
0023 #include <range/v3/functional/bind_back.hpp>
0024 #include <range/v3/iterator/concepts.hpp>
0025 #include <range/v3/iterator/operations.hpp>
0026 #include <range/v3/iterator/traits.hpp>
0027 #include <range/v3/utility/static_const.hpp>
0028 #include <range/v3/view/interface.hpp>
0029 
0030 #include <range/v3/detail/prologue.hpp>
0031 
0032 namespace ranges
0033 {
0034     /// \addtogroup group-actions
0035     /// @{
0036     namespace actions
0037     {
0038         struct slice_fn
0039         {
0040         private:
0041             template<typename D>
0042             using diff_t = range_difference_t<D>;
0043 
0044         public:
0045             // Overloads for the pipe syntax: rng | actions::slice(from, to)
0046             template(typename D)(
0047                 requires integral<D>)
0048             constexpr auto operator()(D from, D to) const
0049             {
0050                 return make_action_closure(bind_back(slice_fn{}, from, to));
0051             }
0052             template(typename D)(
0053                 requires integral<D>)
0054             constexpr auto operator()(D from, detail::from_end_<D> to) const
0055             {
0056                 return make_action_closure(bind_back(slice_fn{}, from, to));
0057             }
0058             template(typename D)(
0059                 requires integral<D>)
0060             constexpr auto operator()(detail::from_end_<D> from, detail::from_end_<D> to)
0061                 const
0062             {
0063                 return make_action_closure(bind_back(slice_fn{}, from, to));
0064             }
0065             template(typename D)(
0066                 requires integral<D>)
0067             constexpr auto operator()(D from, end_fn const & to) const
0068             {
0069                 return make_action_closure(bind_back(slice_fn{}, from, to));
0070             }
0071             template(typename D)(
0072                 requires integral<D>)
0073             constexpr auto operator()(detail::from_end_<D> from, end_fn const & to) const
0074             {
0075                 return make_action_closure(bind_back(slice_fn{}, from, to));
0076             }
0077 
0078             template(typename Rng, typename I = iterator_t<Rng>)(
0079                 requires forward_range<Rng> AND erasable_range<Rng &, I, I>)
0080             Rng operator()(Rng && rng, diff_t<Rng> from, diff_t<Rng> to) const
0081             {
0082                 RANGES_EXPECT(0 <= from && 0 <= to && from <= to);
0083                 RANGES_EXPECT(!sized_range<Rng> || to <= distance(rng));
0084                 ranges::actions::erase(rng, begin(rng), next(begin(rng), from));
0085                 ranges::actions::erase(rng, next(begin(rng), to - from), end(rng));
0086                 return static_cast<Rng &&>(rng);
0087             }
0088 
0089             template(typename Rng, typename I = iterator_t<Rng>)(
0090                 requires bidirectional_range<Rng> AND erasable_range<Rng &, I, I>)
0091             Rng operator()(Rng && rng,
0092                            diff_t<Rng> from,
0093                            detail::from_end_<diff_t<Rng>> to) const
0094             {
0095                 RANGES_EXPECT(0 <= from && to.dist_ <= 0);
0096                 RANGES_EXPECT(!sized_range<Rng> || from - to.dist_ <= distance(rng));
0097                 ranges::actions::erase(rng, begin(rng), next(begin(rng), from));
0098                 if(to.dist_ != 0)
0099                 {
0100                     auto const last = next(begin(rng), end(rng));
0101                     ranges::actions::erase(rng, prev(last, -to.dist_), last);
0102                 }
0103                 return static_cast<Rng &&>(rng);
0104             }
0105 
0106             template(typename Rng, typename I = iterator_t<Rng>)(
0107                 requires bidirectional_range<Rng> AND erasable_range<Rng &, I, I>)
0108             Rng operator()(Rng && rng,
0109                            detail::from_end_<diff_t<Rng>> from,
0110                            detail::from_end_<diff_t<Rng>> to) const
0111             {
0112                 RANGES_EXPECT(from.dist_ <= 0 && to.dist_ <= 0 && from.dist_ <= to.dist_);
0113                 RANGES_EXPECT(!sized_range<Rng> || 0 <= distance(rng) + from.dist_);
0114                 auto last = next(begin(rng), end(rng));
0115                 ranges::actions::erase(rng, prev(last, -to.dist_), last);
0116                 last = next(begin(rng), end(rng));
0117                 ranges::actions::erase(
0118                     rng, begin(rng), prev(last, to.dist_ - from.dist_));
0119                 return static_cast<Rng &&>(rng);
0120             }
0121 
0122             template(typename Rng, typename I = iterator_t<Rng>)(
0123                 requires forward_range<Rng> AND erasable_range<Rng &, I, I>)
0124             Rng operator()(Rng && rng, diff_t<Rng> from, end_fn const &) const
0125             {
0126                 RANGES_EXPECT(0 <= from);
0127                 RANGES_EXPECT(!sized_range<Rng> || from <= distance(rng));
0128                 ranges::actions::erase(rng, begin(rng), next(begin(rng), from));
0129                 return static_cast<Rng &&>(rng);
0130             }
0131 
0132             template(typename Rng, typename I = iterator_t<Rng>)(
0133                 requires bidirectional_range<Rng> AND erasable_range<Rng &, I, I>)
0134             Rng operator()(Rng && rng,
0135                            detail::from_end_<diff_t<Rng>> from,
0136                            end_fn const &) const
0137             {
0138                 RANGES_EXPECT(from.dist_ <= 0);
0139                 RANGES_EXPECT(!sized_range<Rng> || 0 <= distance(rng) + from.dist_);
0140                 auto const last = next(begin(rng), end(rng));
0141                 ranges::actions::erase(rng, begin(rng), prev(last, -from.dist_));
0142                 return static_cast<Rng &&>(rng);
0143             }
0144         };
0145 
0146         /// \relates actions::slice_fn
0147         RANGES_INLINE_VARIABLE(slice_fn, slice)
0148     } // namespace actions
0149     /// @}
0150 } // namespace ranges
0151 
0152 #include <range/v3/detail/epilogue.hpp>
0153 
0154 #endif