14#ifndef RANGES_V3_VIEW_DROP_LAST_HPP
15#define RANGES_V3_VIEW_DROP_LAST_HPP
29#include <range/v3/utility/static_const.hpp>
35#include <range/v3/detail/prologue.hpp>
45 namespace drop_last_view
47 template<
typename Rng>
48 range_size_t<Rng> get_size(Rng & rng, range_difference_t<Rng> n_)
50 RANGES_EXPECT(n_ >= 0);
51 range_size_t<Rng>
const initial_size = ranges::size(rng);
52 range_size_t<Rng>
const n =
static_cast<range_size_t<Rng>
>(n_);
53 return initial_size > n ? initial_size - n : 0;
56 template(
typename Rng)(
57 requires random_access_range<Rng> AND sized_range<Rng>)
58 iterator_t<Rng> get_end(Rng & rng, range_difference_t<Rng> n,
int)
60 return begin(rng) +
static_cast<range_difference_t<Rng>
>(
61 drop_last_view::get_size(rng, n));
63 template(
typename Rng)(
64 requires bidirectional_range<Rng> AND common_range<Rng>)
65 iterator_t<Rng> get_end(Rng & rng, range_difference_t<Rng> n,
long)
67 return prev(end(rng), n, begin(rng));
78 template<mode_enum Mode>
79 using mode_t = std::integral_constant<mode_enum, Mode>;
81 using mode_bidi = mode_t<mode_enum::bidi>;
82 using mode_forward = mode_t<mode_enum::forward>;
83 using mode_sized = mode_t<mode_enum::sized>;
84 using mode_invalid = mode_t<mode_enum::invalid>;
86 template<
typename Rng>
87 constexpr mode_enum get_mode() noexcept
91 return (random_access_range<Rng> && view_<Rng> && sized_range<Rng>) ||
92 (bidirectional_range<Rng> && view_<Rng> &&
95 : sized_range<Rng> && view_<Rng>
97 : forward_range<Rng> && view_<Rng>
112 template<
typename Rng>
113 using mode_of = mode_t<drop_last_view::get_mode<Rng>()>;
118 template<
typename Rng,
typename = detail::drop_last_view::mode_of<Rng>>
122 template<
typename Rng>
124 :
view_interface<drop_last_view<Rng, detail::drop_last_view::mode_bidi>,
125 is_finite<Rng>::value
127 : range_cardinality<Rng>::value>
135 using difference_t = range_difference_t<Rng>;
139 detail::non_propagating_cache<iterator_t<Rng>> end_;
144 : rng_(std::move(rng))
147 RANGES_EXPECT(n >= 0);
152 return ranges::begin(rng_);
154 sentinel_t<Rng> end()
157 end_ = detail::drop_last_view::get_end(rng_, n_, 0);
160 template(
typename CRng = Rng
const)(
164 return ranges::begin(rng_);
166 template(
typename CRng = Rng
const)(
170 return detail::drop_last_view::get_end(rng_, n_, 0);
174 auto CPP_fun(size)()(
177 return detail::drop_last_view::get_size(rng_, n_);
180 auto CPP_fun(size)()(
const
183 return detail::drop_last_view::get_size(rng_, n_);
190 Rng
const & base()
const
196 template<
typename Rng>
199 is_finite<Rng>::value
209 using difference_t = range_difference_t<Rng>;
211 detail::non_propagating_cache<iterator_t<Rng>> probe_begin;
219 : probe_(std::move(probe_first))
230 template<
typename I,
typename S>
231 bool empty(I
const &, adaptor
const & ia, S
const & s)
const
233 return ia.probe_ == s;
237 adaptor begin_adaptor()
240 probe_begin = next(begin(this->base()), n_, end(this->base()));
241 return {*probe_begin};
243 sentinel_adaptor end_adaptor()
251 : drop_last_view::view_adaptor(std::move(rng))
254 RANGES_EXPECT(n >= 0);
258 auto CPP_fun(size)()(
261 return detail::drop_last_view::get_size(this->base(), n_);
264 auto CPP_fun(size)()(
const
267 return detail::drop_last_view::get_size(this->base(), n_);
271 template<
typename Rng>
273 :
view_interface<drop_last_view<Rng, detail::drop_last_view::mode_sized>, finite>
280 using difference_t = range_difference_t<Rng>;
287 : rng_(std::move(rng))
290 RANGES_EXPECT(n >= 0);
293 counted_iterator<iterator_t<Rng>> begin()
295 return {ranges::begin(rng_),
static_cast<difference_t
>(size())};
297 template(
typename CRng = Rng
const)(
299 counted_iterator<iterator_t<CRng>> begin()
const
301 return {ranges::begin(rng_),
static_cast<difference_t
>(size())};
307 range_size_t<Rng> size()
309 return detail::drop_last_view::get_size(this->base(), n_);
312 auto CPP_fun(size)()(
const
315 return detail::drop_last_view::get_size(this->base(), n_);
322 Rng
const & base()
const
328 template<
typename Rng,
typename T>
329 RANGES_INLINE_VAR
constexpr bool enable_borrowed_range<drop_last_view<Rng, T>> =
330 enable_borrowed_range<Rng>;
332#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
333 template<
typename Rng>
342 template(
typename Rng)(
344 constexpr auto operator()(Rng && rng, range_difference_t<Rng> n)
const
347 return {all(
static_cast<Rng &&
>(rng)), n};
353 using drop_last_base_fn::operator();
355 template(
typename Int)(
356 requires detail::integer_like_<Int>)
357 constexpr auto operator()(Int n)
const
369#include <range/v3/detail/epilogue.hpp>
370#include <range/v3/detail/satisfy_boost_range.hpp>
@ sized
satisfies ranges::concepts::sized_range
@ forward
satisfies ranges::concepts::forward_range
The bidirectional_range concept.
The common_range concept.
The forward_range concept.
The random_access_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
Definition adaptor.hpp:110
Definition default_sentinel.hpp:26
Definition drop_last.hpp:120
Definition traits.hpp:128
Definition adaptor.hpp:475
Definition interface.hpp:129
Definition drop_last.hpp:341
Definition drop_last.hpp:352