File indexing completed on 2025-01-18 10:09:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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
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
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
0174
0175 RANGES_INLINE_VARIABLE(drop_exactly_fn, drop_exactly)
0176 }
0177
0178 }
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