15#ifndef RANGES_V3_VIEW_SUBRANGE_HPP
16#define RANGES_V3_VIEW_SUBRANGE_HPP
34#include <range/v3/detail/prologue.hpp>
40 enum class subrange_kind :
bool
52 template<
typename From,
typename To>
53 CPP_concept convertible_to_not_slicing_ =
54 convertible_to<From, To> &&
58 (!(std::is_pointer<decay_t<From>>::value &&
59 std::is_pointer<decay_t<To>>::value &&
60 not_same_as_<std::remove_pointer_t<decay_t<From>>,
61 std::remove_pointer_t<decay_t<To>>>));
63 template<std::
size_t N,
typename T>
69 CPP_requires(pair_like_impl_,
70 requires(T t, tuple_element_fun_t<0, T> p0, tuple_element_fun_t<1, T> p1)
78 CPP_concept pair_like_impl_ = CPP_requires_ref(detail::pair_like_impl_, T);
83 concept (is_complete_)(T),
89 CPP_concept is_complete_ =
90 CPP_concept_ref(is_complete_, T);
93 concept (pair_like_)(T),
94 is_complete_<std::tuple_size<T>> AND
96 detail::pair_like_impl_<T>);
101 CPP_concept pair_like =
102 CPP_concept_ref(detail::pair_like_, T);
105 template(
typename T,
typename U,
typename V)(
106 concept (pair_like_convertible_from_helper_)(T, U, V),
107 convertible_to_not_slicing_<U,
meta::_t<std::tuple_element<0, T>>> AND
108 convertible_to<V,
meta::_t<std::tuple_element<1, T>>>);
112 template<
typename T,
typename U,
typename V>
113 CPP_concept pair_like_convertible_from_helper_ =
114 CPP_concept_ref(pair_like_convertible_from_helper_, T, U, V);
116 template(
typename T,
typename U,
typename V)(
117 concept (pair_like_convertible_from_impl_)(T, U, V),
119 constructible_from<T, U, V> AND
120 pair_like<uncvref_t<T>> AND
121 pair_like_convertible_from_helper_<T, U, V>);
125 template<
typename T,
typename U,
typename V>
126 CPP_concept pair_like_convertible_from_ =
127 CPP_concept_ref(detail::pair_like_convertible_from_impl_, T, U, V);
131 template(
typename R,
typename I,
typename S)(
132 concept (range_convertible_to_impl_)(R, I, S),
133 convertible_to_not_slicing_<iterator_t<R>, I> AND
134 convertible_to<sentinel_t<R>, S>);
138 template<
typename R,
typename I,
typename S>
139 CPP_concept range_convertible_to_ =
141 CPP_concept_ref(detail::range_convertible_to_impl_, R, I, S);
144 template(
typename S,
typename I)(
145 requires sentinel_for<S, I>)
146 constexpr bool is_sized_sentinel_() noexcept
148 return (
bool)sized_sentinel_for<S, I>;
151 template<subrange_kind K,
typename S,
typename I>
152 constexpr bool store_size_() noexcept
154 return K == subrange_kind::sized && !(bool)sized_sentinel_for<S, I>;
162 subrange_kind K =
static_cast<subrange_kind
>(detail::is_sized_sentinel_<S, I>())>
165 template<
typename I,
typename S, subrange_kind K>
166 RANGES_INLINE_VAR
constexpr bool enable_borrowed_range<subrange<I, S, K>> =
true;
174 template(std::size_t N,
typename I,
typename S, subrange_kind K)(
176 constexpr I get(subrange<I, S, K>
const & r)
180 template(std::size_t N,
typename I,
typename S, subrange_kind K)(
182 constexpr S get(subrange<I, S, K>
const & r)
189 template<
typename I,
typename S, subrange_kind K>
192 same_as<S, unreachable_sentinel_t>
194 : K == subrange_kind::sized ? finite : unknown>
195 ,
private _subrange_::adl_hook
200 CPP_assert(K != subrange_kind::sized || !same_as<S, unreachable_sentinel_t>);
202 using size_type = detail::iter_size_t<I>;
208 template(
typename I2)(
209 requires detail::convertible_to_not_slicing_<I2, I> AND
210 (!detail::store_size_<K, S, I>()))
212 : data_{
static_cast<I2 &&
>(i), std::move(s)}
215 template(
typename I2)(
216 requires detail::convertible_to_not_slicing_<I2, I> AND
217 (detail::store_size_<K, S, I>()))
218 constexpr subrange(I2 && i, S s, size_type n)
219 : data_{
static_cast<I2 &&
>(i), std::move(s), n}
223 using D = iter_difference_t<I>;
224 RANGES_EXPECT(n <= (size_type)std::numeric_limits<D>::max());
225 RANGES_EXPECT(ranges::next(first_(), (D)n) == last_());
228 template(
typename I2)(
229 requires detail::convertible_to_not_slicing_<I2, I> AND
231 constexpr subrange(I2 && i, S s, size_type n)
232 : data_{
static_cast<I2 &&
>(i), std::move(s)}
234 RANGES_EXPECT(
static_cast<size_type
>(last_() - first_()) == n);
237 template(
typename R)(
238 requires (!same_as<detail::decay_t<R>,
subrange>) AND
239 detail::range_convertible_to_<R, I, S> AND
240 (!detail::store_size_<K, S, I>()))
242 :
subrange{ranges::begin(r), ranges::end(r)}
245 template(
typename R)(
246 requires (!same_as<detail::decay_t<R>,
subrange>) AND
247 detail::range_convertible_to_<R, I, S> AND
248 (detail::store_size_<K, S, I>()) AND
251 :
subrange{ranges::begin(r), ranges::end(r), ranges::size(r)}
254 template(
typename R)(
255 requires (K == subrange_kind::sized) AND
256 detail::range_convertible_to_<R, I, S>)
257 constexpr subrange(R && r, size_type n)
258 :
subrange{ranges::begin(r), ranges::end(r), n}
262 RANGES_EXPECT(n == ranges::size(r));
266 template(
typename PairLike)(
267 requires (!same_as<PairLike, subrange>) AND
268 detail::pair_like_convertible_from_<PairLike, I const &, S const &>)
269 constexpr operator PairLike()
const
271 return PairLike(first_(), last_());
274 constexpr I begin()
const noexcept(std::is_nothrow_copy_constructible<I>::value)
278 constexpr S end()
const noexcept(std::is_nothrow_copy_constructible<S>::value)
282 constexpr bool empty()
const
284 return first_() == last_();
288 constexpr auto size()
const
289 -> CPP_ret(size_type)(
290 requires (K == subrange_kind::sized))
296 constexpr subrange next(iter_difference_t<I> n = 1)
const
304 RANGES_NODISCARD
constexpr auto prev(iter_difference_t<I> n = 1)
const
313 constexpr subrange & advance(iter_difference_t<I> n)
315 set_size_(get_size_() -
316 static_cast<size_type
>(n - ranges::advance(first_(), n, last_())));
323 detail::store_size_<K, S, I>(),
324 std::tuple<I, S, size_type>,
328 constexpr I & first_()
noexcept
330 return std::get<0>(data_);
332 constexpr const I & first_()
const noexcept
334 return std::get<0>(data_);
336 constexpr S & last_()
noexcept
338 return std::get<1>(data_);
340 constexpr const S & last_()
const noexcept
342 return std::get<1>(data_);
345 constexpr auto get_size_()
const
346 -> CPP_ret(size_type)(
349 return static_cast<size_type
>(last_() - first_());
352 constexpr auto get_size_()
const noexcept
353 -> CPP_ret(size_type)(
354 requires (detail::store_size_<K, S, I>()))
356 return std::get<2>(data_);
358 static constexpr void set_size_(...)
noexcept
361 constexpr auto set_size_(size_type n)
noexcept
363 requires (detail::store_size_<K, S, I>()))
365 std::get<2>(data_) = n;
369#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
370 template<
typename I,
typename S>
374 template(
typename I,
typename S)(
376 subrange(I, S, detail::iter_size_t<I>)
379 template(
typename R)(
385 ? subrange_kind::sized
386 : subrange_kind::unsized>;
388 template(
typename R)(
397 template<
typename I,
typename S>
402 template(
typename I,
typename S)(
405 operator()(I i, S s, detail::iter_size_t<I> n)
const
409 template(
typename R)(
411 constexpr auto operator()(R && r)
const
414 ? subrange_kind::sized
415 : subrange_kind::unsized>
419 template(
typename R)(
422 operator()(R && r, detail::iter_size_t<
iterator_t<R>> n)
const
424 return {(R &&) r, n};
433 using borrowed_subrange_t = detail::maybe_dangling_<R, subrange<iterator_t<R>>>;
436 using safe_subrange_t RANGES_DEPRECATED(
"Use borrowed_subrange_t instead.") =
437 borrowed_subrange_t<R>;
441 using ranges::subrange_kind;
446 static_cast<subrange_kind
>(
447 detail::is_sized_sentinel_<S, I>()))(
452 using ranges::borrowed_subrange_t;
455 using safe_subrange_t RANGES_DEPRECATED(
"Use borrowed_subrange_t instead.") =
456 borrowed_subrange_t<R>;
461RANGES_DIAGNOSTIC_PUSH
462RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
466 template<
typename I,
typename S, ::ranges::subrange_kind K>
467 struct tuple_size<::ranges::subrange<I, S, K>> : std::integral_constant<size_t, 2>
469 template<
typename I,
typename S, ::ranges::subrange_kind K>
474 template<
typename I,
typename S, ::ranges::subrange_kind K>
483#include <range/v3/detail/epilogue.hpp>
@ sized
satisfies ranges::concepts::sized_range
The bidirectional_iterator concept.
The borrowed_range concept.
The random_access_iterator concept.
The sentinel_for concept.
The sized_sentinel_for concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
std::integral_constant< std::size_t, N > size_t
An integral constant wrapper for std::size_t.
Definition meta.hpp:163
typename T::type _t
Type alias for T::type.
Definition meta.hpp:141
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1148
Definition subrange.hpp:396
Definition subrange.hpp:196
Definition interface.hpp:129