31namespace bio::ranges::detail
51template <std::ranges::view urng_t,
bool exactly,
bool or_throw>
52class view_take :
public std::ranges::view_interface<view_take<urng_t, exactly, or_throw>>
62 template <
typename rng_t>
70 using iterator = basic_iterator<urng_t>;
76 using const_iterator = basic_iterator<urng_t const>;
83 view_take() =
default;
84 view_take(view_take
const & rhs) =
default;
85 view_take(view_take && rhs)
noexcept =
default;
86 view_take & operator=(view_take
const & rhs) =
default;
87 view_take & operator=(view_take && rhs)
noexcept =
default;
88 ~view_take() =
default;
95 constexpr view_take(urng_t _urange,
size_t const _size) : urange{
std::
move(_urange)}, target_size{_size}
97 if constexpr (std::ranges::sized_range<urng_t>)
99 if (std::ranges::size(urange) < target_size)
101 if constexpr (exactly && or_throw)
104 "You are trying to construct a views::take_exactly_or_throw from a range that is strictly "
109 target_size = std::ranges::size(urange);
121 template <std::ranges::viewable_range rng_t>
122 requires std::constructible_from<rng_t, std::views::all_t<rng_t>>
123 constexpr view_take(rng_t && _urange,
size_t const _size) :
124 view_take{
std::views::all(
std::
forward<rng_t>(_urange)), _size}
144 constexpr auto begin() noexcept
146 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
153 constexpr auto begin() const noexcept
154 requires const_iterable_range<urng_t>
156 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
175 constexpr auto end() noexcept
177 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
180 return std::ranges::end(urange);
184 constexpr auto end() const noexcept
185 requires const_iterable_range<urng_t>
187 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
190 return std::ranges::cend(urange);
209 constexpr auto size() const noexcept
210 requires exactly ||
std::ranges::sized_range<urng_t>
218template <
typename urng_t,
bool exactly = false,
bool or_throw = false>
219view_take(urng_t &&,
size_t) -> view_take<std::views::all_t<urng_t>, exactly, or_throw>;
223template <std::ranges::view urng_t,
bool exactly,
bool or_throw>
224template <
typename rng_t>
225class view_take<urng_t, exactly, or_throw>::basic_iterator :
226 public inherited_iterator_base<basic_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
230 using base_base_t = std::ranges::iterator_t<rng_t>;
232 using base_t = inherited_iterator_base<basic_iterator, std::ranges::iterator_t<rng_t>>;
235 using sentinel_type = std::ranges::sentinel_t<urng_t>;
251 basic_iterator() =
default;
252 basic_iterator(basic_iterator
const & rhs) =
default;
253 basic_iterator(basic_iterator && rhs)
noexcept =
default;
254 basic_iterator & operator=(basic_iterator
const & rhs) =
default;
255 basic_iterator & operator=(basic_iterator && rhs)
noexcept =
default;
256 ~basic_iterator() =
default;
259 constexpr basic_iterator(base_base_t
const & it)
noexcept(
noexcept(base_t{it})) : base_t{std::move(it)} {}
262 constexpr basic_iterator(base_base_t it,
264 size_t const _max_pos,
265 view_take * host =
nullptr) noexcept(noexcept(base_t{it})) :
266 base_t{
std::
move(it)}, pos{_pos}, max_pos(_max_pos)
284 using pointer = detail::iter_pointer_t<base_base_t>;
286 using iterator_category = detail::iterator_category_tag_t<base_base_t>;
288 using iterator_concept = detail::iterator_concept_tag_t<base_base_t>;
297 constexpr basic_iterator & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
299 base_t::operator++();
301 if constexpr (exactly && !std::forward_iterator<base_base_t>)
302 --host_ptr->target_size;
307 constexpr basic_iterator operator++(
int)
noexcept(
noexcept(++std::declval<basic_iterator &>()) &&
308 std::is_nothrow_copy_constructible_v<basic_iterator>)
310 basic_iterator cpy{*
this};
316 constexpr basic_iterator & operator--() noexcept(noexcept(--
std::declval<base_base_t &>()))
317 requires
std::bidirectional_iterator<base_base_t>
319 base_t::operator--();
325 constexpr basic_iterator operator--(
int)
noexcept(
noexcept(--std::declval<basic_iterator &>()) &&
326 std::is_nothrow_copy_constructible_v<basic_iterator>)
327 requires std::bidirectional_iterator<base_base_t>
329 basic_iterator cpy{*
this};
335 constexpr basic_iterator & operator+=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() +=
337 requires std::random_access_iterator<base_base_t>
339 base_t::operator+=(skip);
345 constexpr basic_iterator & operator-=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() -=
347 requires std::random_access_iterator<base_base_t>
349 base_t::operator-=(skip);
361 constexpr bool operator==(basic_iterator
const & rhs)
const
362 noexcept(!or_throw &&
noexcept(std::declval<base_base_t &>() == std::declval<base_base_t &>()))
363 requires std::forward_iterator<base_base_t>
365 return *base_t::this_to_base() == *rhs.this_to_base();
369 constexpr bool operator==(sentinel_type
const & rhs)
const
370 noexcept(!or_throw &&
noexcept(std::declval<base_base_t const &>() == std::declval<sentinel_type const &>()))
375 if (*base_t::this_to_base() == rhs)
377 if constexpr (or_throw)
389 constexpr friend bool operator==(sentinel_type
const & lhs,
390 basic_iterator
const & rhs)
noexcept(
noexcept(rhs == lhs))
406 noexcept(
noexcept(std::declval<base_base_t &>()[0]))
407 requires std::random_access_iterator<base_base_t>
409 return base_base_t::operator[](n);
421template <
bool exactly,
bool or_throw>
425 constexpr auto operator()(
size_t const size)
const {
return adaptor_from_functor{*
this,
size}; }
430 template <std::ranges::range urng_t>
431 constexpr auto operator()(urng_t && urange,
size_t target_size)
const
433 static_assert(std::ranges::viewable_range<urng_t>,
434 "The views::take adaptor can only be passed viewable_ranges, i.e. Views or &-to-non-View.");
437 if constexpr (std::ranges::sized_range<urng_t>)
439 if constexpr (or_throw)
441 if (target_size > std::ranges::size(urange))
444 "You are trying to construct a views::take_exactly_or_throw from a "
445 "range that is strictly smaller."};
450 target_size = std::min<size_t>(target_size, std::ranges::size(urange));
457 return urange.substr(0, target_size);
460 else if constexpr (meta::is_type_specialisation_of_v<std::remove_cvref_t<urng_t>,
std::basic_string> &&
461 std::is_const_v<std::remove_reference_t<urng_t>>)
466 else if constexpr (std::ranges::borrowed_range<urng_t> && std::ranges::contiguous_range<urng_t> &&
467 std::ranges::sized_range<urng_t>)
469 return std::span{std::ranges::data(urange), target_size};
472 else if constexpr (std::ranges::borrowed_range<urng_t> && std::ranges::random_access_range<urng_t> &&
473 std::ranges::sized_range<urng_t>)
475 return std::ranges::subrange<std::ranges::iterator_t<urng_t>, std::ranges::iterator_t<urng_t>>{
483 return view_take<std::views::all_t<urng_t>, exactly, or_throw>{std::forward<urng_t>(urange), target_size};
constexpr auto size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:517
std::remove_cvref_t< decltype(std::ignore)> ignore_t
Return the type of std::ignore with const, volatile and references removed (type trait).
Definition: basic.hpp:48
Provides the bio::ranges::detail::inherited_iterator_base template.
Additional non-standard concepts for ranges.
Adaptations of concepts from the standard library.
Auxiliary header for the views submodule .
Provides various traits to inspect templates.
Provides various transformation traits used by the range module.