File indexing completed on 2025-01-18 10:09:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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
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
0147 RANGES_INLINE_VARIABLE(slice_fn, slice)
0148 }
0149
0150 }
0151
0152 #include <range/v3/detail/epilogue.hpp>
0153
0154 #endif