14 #ifndef RANGES_V3_VIEW_SLICE_HPP
15 #define RANGES_V3_VIEW_SLICE_HPP
17 #include <type_traits>
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>>
179 using detail::slice_view_<Rng, (bool)random_access_range<Rng>>::slice_view_;
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)(
206 requires borrowed_range<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)(
221 requires viewable_range<Rng> AND input_range<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)(
234 requires viewable_range<Rng> AND input_range<Rng> AND sized_range<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)(
250 requires viewable_range<Rng> AND
251 (forward_range<Rng> || (input_range<Rng> && sized_range<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)(
267 requires viewable_range<Rng> AND input_range<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)(
275 requires viewable_range<Rng> AND
276 (forward_range<Rng> || (input_range<Rng> && sized_range<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
302 template(
typename Int)(
303 requires detail::integer_like_<Int>)
304 constexpr
auto operator()(Int from, detail::from_end_<Int> to)
const
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
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
337 #include <range/v3/detail/epilogue.hpp>
338 #include <range/v3/detail/satisfy_boost_range.hpp>
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
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: slice.hpp:178
Definition: subrange.hpp:196
Definition: drop_exactly.hpp:135
Definition: slice.hpp:195
Definition: slice.hpp:292