15 #include <range/v3/algorithm/copy.hpp> 54 template <std::ranges::view urng_t,
bool exactly,
bool or_throw>
55 class view_take :
public std::ranges::view_interface<view_take<urng_t, exactly, or_throw>>
66 template <
typename rng_t>
67 class iterator_type :
public inherited_iterator_base<iterator_type<rng_t>, std::ranges::iterator_t<rng_t>>
71 using base_base_t = std::ranges::iterator_t<rng_t>;
73 using base_t = inherited_iterator_base<iterator_type, std::ranges::iterator_t<rng_t>>;
76 using sentinel_type = std::ranges::sentinel_t<urng_t>;
92 constexpr iterator_type() =
default;
93 constexpr iterator_type(iterator_type
const & rhs) =
default;
94 constexpr iterator_type(iterator_type && rhs) =
default;
95 constexpr iterator_type & operator=(iterator_type
const & rhs) =
default;
96 constexpr iterator_type & operator=(iterator_type && rhs) =
default;
97 ~iterator_type() =
default;
100 constexpr iterator_type(base_base_t
const & it) noexcept(noexcept(base_t{it})) :
105 constexpr iterator_type(base_base_t it,
size_t const _pos,
size_t const _max_pos, view_take * host =
nullptr) noexcept(noexcept(base_t{it})) :
106 base_t{
std::move(it)}, pos{_pos}, max_pos(_max_pos)
126 using iterator_category = iterator_tag_t<base_base_t>;
134 constexpr iterator_type & operator++() noexcept(noexcept(++
std::declval<base_t &>()))
137 base_t::operator++();
139 if constexpr (exactly && !std::forward_iterator<base_base_t>)
140 --host_ptr->target_size;
145 constexpr iterator_type operator++(
int) noexcept(noexcept(++std::declval<iterator_type &>()) &&
146 std::is_nothrow_copy_constructible_v<iterator_type>)
148 iterator_type cpy{*
this};
154 constexpr iterator_type & operator--() noexcept(noexcept(--
std::declval<base_base_t &>()))
156 requires
std::bidirectional_iterator<base_base_t>
159 base_t::operator--();
165 constexpr iterator_type operator--(
int) noexcept(noexcept(--std::declval<iterator_type &>()) &&
166 std::is_nothrow_copy_constructible_v<iterator_type>)
168 requires std::bidirectional_iterator<base_base_t>
171 iterator_type cpy{*
this};
177 constexpr iterator_type & operator+=(difference_type
const skip) noexcept(noexcept(std::declval<base_t &>() += skip))
179 requires std::random_access_iterator<base_base_t>
182 base_t::operator+=(skip);
188 constexpr iterator_type & operator-=(difference_type
const skip) noexcept(noexcept(std::declval<base_t &>() -= skip))
190 requires std::random_access_iterator<base_base_t>
193 base_t::operator-=(skip);
204 constexpr
bool operator==(iterator_type
const & rhs)
const 206 noexcept(!or_throw && noexcept(std::declval<base_base_t &>() == std::declval<base_base_t &>()))
208 requires
std::forward_iterator<base_base_t>
211 return *base_t::this_to_base() == *rhs.this_to_base();
215 constexpr
bool operator==(sentinel_type
const & rhs)
const 216 noexcept(!or_throw && noexcept(std::declval<base_base_t const &>() == std::declval<sentinel_type const &>()))
221 if (*base_t::this_to_base() == rhs)
223 if constexpr (or_throw)
224 throw unexpected_end_of_input{
"Reached end of input before designated size."};
235 constexpr
friend bool operator==(sentinel_type
const & lhs, iterator_type
const & rhs) noexcept(noexcept(rhs == lhs))
241 constexpr
bool operator!=(sentinel_type
const & rhs)
const 242 noexcept(noexcept(std::declval<iterator_type &>() == rhs))
244 return !(*
this == rhs);
248 constexpr
bool operator!=(iterator_type
const & rhs)
const 249 noexcept(noexcept(std::declval<iterator_type &>() == rhs))
251 requires std::forward_iterator<base_base_t>
254 return !(*
this == rhs);
258 constexpr
friend bool operator!=(sentinel_type
const & lhs, iterator_type
const & rhs) noexcept(noexcept(rhs != lhs))
274 noexcept(noexcept(std::declval<base_base_t &>()[0]))
276 requires
std::random_access_iterator<base_base_t>
279 return base_base_t::operator[](n);
287 using reference = reference_t<urng_t>;
290 using const_reference = detail::transformation_trait_or_t<seqan3::reference<urng_t const>,
void>;
292 using value_type = value_type_t<urng_t>;
295 transformation_trait_or_t<seqan3::size_type<urng_t>,
size_t>,
298 using difference_type = difference_type_t<urng_t>;
300 using iterator = iterator_type<urng_t>;
302 using const_iterator = detail::transformation_trait_or_t<std::type_identity<iterator_type<urng_t const>>,
void>;
309 constexpr view_take() =
default;
310 constexpr view_take(view_take
const & rhs) =
default;
311 constexpr view_take(view_take && rhs) =
default;
312 constexpr view_take & operator=(view_take
const & rhs) =
default;
313 constexpr view_take & operator=(view_take && rhs) =
default;
314 ~view_take() =
default;
321 constexpr view_take(urng_t _urange,
size_t const _size)
322 : urange{
std::move(_urange)}, target_size{_size}
324 if constexpr (std::ranges::sized_range<urng_t>)
328 if constexpr (exactly && or_throw)
332 "You are trying to construct a views::take_exactly_or_throw from a range that is strictly " 350 template <std::ranges::viewable_range rng_t>
354 constexpr view_take(rng_t && _urange,
size_t const _size)
375 constexpr
auto begin() noexcept
377 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t>)
378 return std::ranges::begin(urange);
380 return iterator{std::ranges::begin(urange), 0, target_size,
this};
384 constexpr
auto begin() const noexcept
385 requires const_iterable_range<urng_t>
387 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t>)
388 return std::ranges::cbegin(urange);
390 return const_iterator{std::ranges::cbegin(urange), 0, target_size};
394 constexpr
auto cbegin() const noexcept
395 requires const_iterable_range<urng_t>
397 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t>)
398 return std::ranges::cbegin(urange);
400 return const_iterator{std::ranges::cbegin(urange), 0, target_size};
416 constexpr
auto end() noexcept
418 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t>)
419 return std::ranges::begin(urange) + target_size;
421 return std::ranges::end(urange);
425 constexpr
auto end() const noexcept
426 requires const_iterable_range<urng_t>
428 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t>)
429 return std::ranges::cbegin(urange) + target_size;
431 return std::ranges::cend(urange);
435 constexpr
auto cend() const noexcept
436 requires const_iterable_range<urng_t>
438 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t>)
439 return std::ranges::cbegin(urange) + target_size;
441 return std::ranges::cend(urange);
459 constexpr size_type
size() const noexcept
460 requires exactly ||
std::
ranges::sized_range<urng_t>
468 template <
typename urng_t,
469 bool exactly =
false,
470 bool or_throw =
false>
471 view_take(urng_t && ,
size_t) -> view_take<std::ranges::all_view<urng_t>, exactly, or_throw>;
480 template <
bool exactly,
bool or_throw>
484 constexpr
auto operator()(
size_t const size)
const 486 return adaptor_from_functor{*
this, size};
492 template <std::ranges::range urng_t>
493 constexpr
auto operator()(urng_t && urange,
size_t target_size)
const 495 static_assert(std::ranges::viewable_range<urng_t>,
496 "The views::take adaptor can only be passed viewable_ranges, i.e. Views or &-to-non-View.");
499 if constexpr (std::ranges::sized_range<urng_t>)
501 if constexpr (or_throw)
506 "range that is strictly smaller."};
518 return urange.substr(0, target_size);
521 else if constexpr (is_type_specialisation_of_v<remove_cvref_t<urng_t>,
std::basic_string> &&
527 else if constexpr (forwarding_range<urng_t> &&
528 std::ranges::contiguous_range<urng_t> &&
529 std::ranges::sized_range<urng_t>)
531 return std::span{std::ranges::data(urange), target_size};
534 else if constexpr (forwarding_range<urng_t> &&
535 std::ranges::random_access_range<urng_t> &&
536 std::ranges::sized_range<urng_t>)
538 return std::ranges::subrange<std::ranges::iterator_t<urng_t>, std::ranges::iterator_t<urng_t>>
540 std::ranges::begin(urange),
541 std::ranges::begin(urange) + target_size,
548 return view_take<std::ranges::all_view<urng_t>, exactly, or_throw>
550 std::forward<urng_t>(urange),
624 inline auto constexpr
take = detail::take_fn<false, false>{};
Provides exceptions used in the I/O module.
Provides C++20 additions to the <iterator> header.
Provides various shortcuts for common std::ranges functions.
Provides seqan3::type_list and auxiliary type traits.
Provides the seqan3::detail::inherited_iterator_base template.
SeqAn specific customisations in the standard namespace.
auto constexpr take
A view adaptor that returns the first size elements from the underlying range (or less if the underly...
Definition: take.hpp:624
detail::search_mode_all constexpr all
Configuration element to receive all hits within the error bounds.
Definition: mode.hpp:43
The SeqAn namespace for views.
Definition: view_to_simd.hpp:672
Provides various transformation traits for use on iterators.
Additional non-standard concepts for ranges.
Adaptations of concepts from the Ranges TS.
Provides std::span from the C++20 standard library.
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:116
Definition: aligned_sequence_concept.hpp:36
The std::constructible_from concept specifies that a variable of type T can be initialized with the g...
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
Provides C++20 additions to the type_traits header.
Adaptations of algorithms from the Ranges TS.
Provides various transformation traits used by the range module.
Adaptations of concepts from the standard library.
Auxiliary header for the views submodule .