31namespace bio::ranges::detail
53template <std::ranges::view urng_t,
bool exactly,
bool or_throw>
56:
public std::ranges::view_interface<view_take<urng_t, exactly, or_throw>>
67 template <
typename rng_t>
75 using iterator = basic_iterator<urng_t>;
81 using const_iterator = basic_iterator<urng_t const>;
88 view_take() =
default;
89 view_take(view_take
const & rhs) =
default;
90 view_take(view_take && rhs)
noexcept =
default;
91 view_take & operator=(view_take
const & rhs) =
default;
92 view_take & operator=(view_take && rhs)
noexcept =
default;
93 ~view_take() =
default;
100 constexpr view_take(urng_t _urange,
size_t const _size) : urange{
std::
move(_urange)}, target_size{_size}
102 if constexpr (std::ranges::sized_range<urng_t>)
104 if (std::ranges::size(urange) < target_size)
106 if constexpr (exactly && or_throw)
109 "You are trying to construct a views::take_exactly_or_throw from a range that is strictly "
114 target_size = std::ranges::size(urange);
126 template <std::ranges::viewable_range rng_t>
127 requires std::constructible_from<rng_t, std::views::all_t<rng_t>>
128 constexpr view_take(rng_t && _urange,
size_t const _size) :
129 view_take{
std::views::all(
std::
forward<rng_t>(_urange)), _size}
149 constexpr auto begin() noexcept
151 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
158 constexpr auto begin() const noexcept
159 requires const_iterable_range<urng_t>
161 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
180 constexpr auto end() noexcept
182 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
185 return std::ranges::end(urange);
189 constexpr auto end() const noexcept
190 requires const_iterable_range<urng_t>
192 if constexpr (std::ranges::random_access_range<urng_t> && (std::ranges::sized_range<urng_t> || exactly))
195 return std::ranges::end(urange);
214 constexpr auto size() const noexcept
215 requires exactly ||
std::ranges::sized_range<urng_t>
223template <
typename urng_t,
bool exactly = false,
bool or_throw = false>
224view_take(urng_t &&,
size_t) -> view_take<std::views::all_t<urng_t>, exactly, or_throw>;
228template <std::ranges::view urng_t,
bool exactly,
bool or_throw>
229template <
typename rng_t>
230class view_take<urng_t, exactly, or_throw>::basic_iterator
232 :
public inherited_iterator_base<basic_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
237 using base_base_t = std::ranges::iterator_t<rng_t>;
239 using base_t = inherited_iterator_base<basic_iterator, std::ranges::iterator_t<rng_t>>;
242 using sentinel_type = std::ranges::sentinel_t<urng_t>;
258 basic_iterator() =
default;
259 basic_iterator(basic_iterator
const & rhs) =
default;
260 basic_iterator(basic_iterator && rhs)
noexcept =
default;
261 basic_iterator & operator=(basic_iterator
const & rhs) =
default;
262 basic_iterator & operator=(basic_iterator && rhs)
noexcept =
default;
263 ~basic_iterator() =
default;
266 constexpr basic_iterator(base_base_t
const & it)
noexcept(
noexcept(base_t{it})) : base_t{std::move(it)} {}
269 constexpr basic_iterator(base_base_t it,
271 size_t const _max_pos,
272 view_take * host =
nullptr) noexcept(noexcept(base_t{it})) :
273 base_t{
std::
move(it)}, pos{_pos}, max_pos(_max_pos)
291 using pointer = detail::iter_pointer_t<base_base_t>;
293 using iterator_category = detail::iterator_category_tag_t<base_base_t>;
295 using iterator_concept = detail::iterator_concept_tag_t<base_base_t>;
304 constexpr basic_iterator & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
306 base_t::operator++();
308 if constexpr (exactly && !std::forward_iterator<base_base_t>)
309 --host_ptr->target_size;
314 constexpr basic_iterator operator++(
int)
noexcept(
noexcept(++std::declval<basic_iterator &>()) &&
315 std::is_nothrow_copy_constructible_v<basic_iterator>)
317 basic_iterator cpy{*
this};
323 constexpr basic_iterator & operator--() noexcept(noexcept(--
std::declval<base_base_t &>()))
324 requires
std::bidirectional_iterator<base_base_t>
326 base_t::operator--();
332 constexpr basic_iterator operator--(
int)
noexcept(
noexcept(--std::declval<basic_iterator &>()) &&
333 std::is_nothrow_copy_constructible_v<basic_iterator>)
334 requires std::bidirectional_iterator<base_base_t>
336 basic_iterator cpy{*
this};
342 constexpr basic_iterator & operator+=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() +=
344 requires std::random_access_iterator<base_base_t>
346 base_t::operator+=(skip);
352 constexpr basic_iterator & operator-=(difference_type
const skip)
noexcept(
noexcept(std::declval<base_t &>() -=
354 requires std::random_access_iterator<base_base_t>
356 base_t::operator-=(skip);
368 constexpr bool operator==(basic_iterator
const & rhs)
const
369 noexcept(!or_throw &&
noexcept(std::declval<base_base_t &>() == std::declval<base_base_t &>()))
370 requires std::forward_iterator<base_base_t>
372 return *base_t::this_to_base() == *rhs.this_to_base();
376 constexpr friend bool operator==(basic_iterator
const & lhs, sentinel_type
const & rhs)
noexcept(
377 !or_throw &&
noexcept(std::declval<base_base_t const &>() == std::declval<sentinel_type const &>()))
379 if (lhs.pos >= lhs.max_pos)
382 if (
static_cast<base_base_t
>(lhs) == rhs)
384 if constexpr (or_throw)
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.