14#ifndef RANGES_V3_VIEW_SLICE_HPP
15#define RANGES_V3_VIEW_SLICE_HPP
31#include <range/v3/utility/static_const.hpp>
38#include <range/v3/detail/prologue.hpp>
45 template<
typename Rng,
typename Int>
46 iterator_t<Rng> pos_at_(Rng && rng, Int i, input_range_tag, std::true_type)
48 RANGES_EXPECT(0 <= i);
49 return next(ranges::begin(rng), i);
52 template<
typename Rng,
typename Int>
53 iterator_t<Rng> pos_at_(Rng && rng, Int i, bidirectional_range_tag,
59 if(RANGES_CONSTEXPR_IF(sized_range<Rng> && !common_range<Rng>))
60 return next(ranges::begin(rng), distance(rng) + i);
62 return next(ranges::next(ranges::begin(rng), ranges::end(rng)), i);
64 return next(ranges::begin(rng), i);
67 template<
typename Rng,
typename Int>
68 iterator_t<Rng> pos_at_(Rng && rng, Int i, input_range_tag, std::false_type)
70 RANGES_EXPECT(i >= 0 || (
bool)sized_range<Rng> || (
bool)forward_range<Rng>);
72 return next(ranges::begin(rng), distance(rng) + i);
73 return next(ranges::begin(rng), i);
76 template<
typename Rng,
bool IsRandomAccess>
77 struct slice_view_ : view_facade<slice_view<Rng>, finite>
82 range_difference_t<Rng> from_, count_;
83 detail::non_propagating_cache<iterator_t<Rng>> begin_;
85 iterator_t<Rng> get_begin_()
88 begin_ = detail::pos_at_(
89 rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{});
94 slice_view_() =
default;
95 constexpr slice_view_(Rng rng, range_difference_t<Rng> from,
96 range_difference_t<Rng> count)
97 : rng_(std::move(rng))
101 counted_iterator<iterator_t<Rng>> begin()
103 return make_counted_iterator(get_begin_(), count_);
105 default_sentinel_t end()
111 return static_cast<detail::iter_size_t<iterator_t<Rng>
>>(count_);
119 template<
typename Rng>
120 struct slice_view_<Rng, true> : view_interface<slice_view<Rng>, finite>
124 range_difference_t<Rng> from_, count_;
127 slice_view_() =
default;
128 constexpr slice_view_(Rng rng, range_difference_t<Rng> from,
129 range_difference_t<Rng> count)
130 : rng_(std::move(rng))
134 RANGES_EXPECT(0 <= count_);
136 iterator_t<Rng> begin()
138 return detail::pos_at_(
139 rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{});
141 iterator_t<Rng> end()
143 return detail::pos_at_(
144 rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{}) +
147 template(
typename BaseRng = Rng)(
148 requires range<BaseRng const>)
149 iterator_t<BaseRng const> begin()
const
151 return detail::pos_at_(
152 rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{});
154 template(
typename BaseRng = Rng)(
155 requires range<BaseRng const>)
156 iterator_t<BaseRng const> end()
const
158 return detail::pos_at_(
159 rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{}) +
164 return static_cast<detail::iter_size_t<iterator_t<Rng>
>>(count_);
176 template<
typename Rng>
177 struct slice_view : detail::slice_view_<Rng, (bool)random_access_range<Rng>>
182 template<
typename Rng>
183 RANGES_INLINE_VAR
constexpr bool enable_borrowed_range<slice_view<Rng>> =
184 enable_borrowed_range<Rng>;
186#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
187 template<
typename Rng>
188 slice_view(Rng &&, range_difference_t<Rng>, range_difference_t<Rng>)
189 ->slice_view<views::all_t<Rng>>;
197 template<
typename Rng>
199 range_difference_t<Rng> from,
200 range_difference_t<Rng> count,
203 return {all(
static_cast<Rng &&
>(rng)), from, count};
205 template(
typename Rng)(
208 range_difference_t<Rng> from,
209 range_difference_t<Rng> count,
214 detail::pos_at_(rng, from, range_tag_of<Rng>{}, is_infinite<Rng>{});
215 return {it, it + count};
220 template(
typename Rng)(
222 constexpr auto operator()(Rng && rng,
223 range_difference_t<Rng> from,
224 range_difference_t<Rng> to)
const
226 RANGES_EXPECT(0 <= from && from <= to);
227 return slice_base_fn::impl_(
228 static_cast<Rng &&
>(rng), from, to - from, range_tag_of<Rng>{});
233 template(
typename Rng)(
235 auto operator()(Rng && rng,
236 range_difference_t<Rng> from,
237 detail::from_end_of_t<Rng> to)
const
239 static_assert(!is_infinite<Rng>::value,
240 "Can't index from the end of an infinite range!");
241 RANGES_EXPECT(0 <= from);
242 RANGES_ASSERT(from <= distance(rng) + to.dist_);
243 return slice_base_fn::impl_(
static_cast<Rng &&
>(rng),
245 distance(rng) + to.dist_ - from,
246 range_tag_of<Rng>{});
249 template(
typename Rng)(
252 auto operator()(Rng && rng,
253 detail::from_end_of_t<Rng> from,
254 detail::from_end_of_t<Rng> to)
const
256 static_assert(!is_infinite<Rng>::value,
257 "Can't index from the end of an infinite range!");
258 RANGES_EXPECT(from.dist_ <= to.dist_);
259 return slice_base_fn::impl_(
static_cast<Rng &&
>(rng),
261 to.dist_ - from.dist_,
263 common_range_tag_of<Rng>{});
266 template(
typename Rng)(
268 auto operator()(Rng && rng, range_difference_t<Rng> from, end_fn)
const
270 RANGES_EXPECT(0 <= from);
271 return ranges::views::drop_exactly(
static_cast<Rng &&
>(rng), from);
274 template(
typename Rng)(
277 auto operator()(Rng && rng,
278 detail::from_end_of_t<Rng> from,
281 static_assert(!is_infinite<Rng>::value,
282 "Can't index from the end of an infinite range!");
283 return slice_base_fn::impl_(
static_cast<Rng &&
>(rng),
287 common_range_tag_of<Rng>{});
293 using slice_base_fn::operator();
296 template(
typename Int)(
297 requires detail::integer_like_<Int>)
298 constexpr auto operator()(Int from, Int to)
const
300 return make_view_closure(bind_back(
slice_base_fn{}, from, to));
302 template(
typename Int)(
303 requires detail::integer_like_<Int>)
304 constexpr auto operator()(Int from, detail::from_end_<Int> to)
const
306 return make_view_closure(bind_back(
slice_base_fn{}, from, to));
308 template(
typename Int)(
309 requires detail::integer_like_<Int>)
310 constexpr auto operator()(detail::from_end_<Int> from,
311 detail::from_end_<Int> to)
const
313 return make_view_closure(bind_back(
slice_base_fn{}, from, to));
315 template(
typename Int)(
316 requires detail::integer_like_<Int>)
317 constexpr auto operator()(Int from, end_fn)
const
319 return make_view_closure(
322 template(
typename Int)(
323 requires detail::integer_like_<Int>)
324 constexpr auto operator()(detail::from_end_<Int> from, end_fn to)
const
326 return make_view_closure(bind_back(
slice_base_fn{}, from, to));
332 RANGES_INLINE_VARIABLE(
slice_fn, slice)
337#include <range/v3/detail/epilogue.hpp>
338#include <range/v3/detail/satisfy_boost_range.hpp>
The borrowed_range concept.
The forward_range concept.
The random_access_range concept.
The viewable_range concept.
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition meta.hpp:1696
_t< detail::count_< L, T > > count
Count the number of times a type T appears in the list L.
Definition meta.hpp:2725
Definition concepts.hpp:305
Definition concepts.hpp:277
Definition concepts.hpp:268
Definition subrange.hpp:196
Definition drop_exactly.hpp:135