32 namespace seqan3::detail
52 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
53 class view_take_until :
public std::ranges::view_interface<view_take_until<urng_t, fun_t, or_throw, and_consume>>
57 static_assert(std::invocable<fun_t, std::ranges::range_reference_t<urng_t>>,
58 "The functor type for views::take_until must model"
59 "std::invocable<fun_t, std::ranges::range_reference_t<urng_t>>.");
60 static_assert(std::convertible_to<
std::result_of_t<fun_t&&(std::ranges::range_reference_t<urng_t>)>,
bool>,
61 "The result type of the functor for views::take_until must be a boolean.");
67 ranges::semiregular_t<fun_t> fun;
71 std::regular_invocable<fun_t, std::ranges::range_reference_t<urng_t>>;
73 template <
typename rng_t>
76 template <
bool is_const_range>
79 template <
typename rng_t>
80 class basic_consume_iterator;
88 basic_consume_iterator<urng_t>,
89 basic_iterator<urng_t>>;
92 using const_iterator = basic_iterator<urng_t const>;
99 view_take_until() =
default;
100 constexpr view_take_until(view_take_until
const & rhs) =
default;
101 constexpr view_take_until(view_take_until && rhs) =
default;
102 constexpr view_take_until & operator=(view_take_until
const & rhs) =
default;
103 constexpr view_take_until & operator=(view_take_until && rhs) =
default;
104 ~view_take_until() =
default;
110 view_take_until(urng_t _urange, fun_t _fun)
119 template <std::ranges::viewable_range rng_t>
121 requires std::constructible_from<rng_t, std::views::all_t<rng_t>>
123 view_take_until(rng_t && _urange, fun_t _fun)
144 iterator
begin() noexcept
146 return {std::ranges::begin(urange),
static_cast<fun_t &
>(fun), std::ranges::end(urange)};
150 const_iterator
begin() const noexcept
151 requires const_iterable
153 return {std::ranges::cbegin(urange),
static_cast<fun_t
const &
>(fun), std::ranges::cend(urange)};
171 if constexpr (and_consume && !std::ranges::forward_range<urng_t>)
172 return std::ranges::end(urange);
174 return basic_sentinel<false>{std::ranges::end(urange), fun};
178 auto end() const noexcept
179 requires const_iterable
181 if constexpr (and_consume && !std::ranges::forward_range<urng_t>)
182 return std::ranges::cend(urange);
184 return basic_sentinel<true>{std::ranges::cend(urange),
static_cast<fun_t
const &
>(fun)};
191 template <
typename urng_t,
typename fun_t,
bool or_throw = false,
bool and_consume = false>
192 view_take_until(urng_t &&, fun_t) -> view_take_until<std::views::all_t<urng_t>, fun_t, or_throw, and_consume>;
196 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
197 template <
typename rng_t>
198 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_iterator :
199 public inherited_iterator_base<basic_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
203 using base_base_t = std::ranges::iterator_t<rng_t>;
205 using base_t = inherited_iterator_base<basic_iterator, std::ranges::iterator_t<rng_t>>;
207 using sentinel_type = std::ranges::sentinel_t<rng_t>;
220 constexpr basic_iterator() =
default;
221 constexpr basic_iterator(basic_iterator
const & rhs) =
default;
222 constexpr basic_iterator(basic_iterator && rhs) =
default;
223 constexpr basic_iterator & operator=(basic_iterator
const & rhs) =
default;
224 constexpr basic_iterator & operator=(basic_iterator && rhs) =
default;
225 ~basic_iterator() =
default;
228 basic_iterator(base_base_t it) noexcept(noexcept(base_t{it})) :
233 basic_iterator(base_base_t it,
235 sentinel_type ) noexcept(noexcept(base_t{it})) :
236 base_t{
std::
move(it)}, fun{_fun}
246 using difference_type = std::iter_difference_t<base_base_t>;
248 using value_type = std::iter_value_t<base_base_t>;
250 using reference = std::iter_reference_t<base_base_t>;
252 using pointer = detail::iter_pointer_t<base_base_t>;
254 using iterator_category = detail::iterator_category_tag_t<base_base_t>;
256 using iterator_concept = detail::iterator_concept_tag_t<base_base_t>;
260 base_base_t base() const
262 requires
std::copy_constructible<base_base_t>
265 return *this->this_to_base();
271 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
272 template <
typename rng_t>
273 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_consume_iterator :
274 public inherited_iterator_base<basic_consume_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
278 using base_base_t = std::ranges::iterator_t<rng_t>;
280 using base_t = inherited_iterator_base<basic_consume_iterator, std::ranges::iterator_t<rng_t>>;
290 using sentinel_type = std::ranges::sentinel_t<rng_t>;
293 sentinel_type stored_end;
296 bool at_end_gracefully =
false;
303 constexpr basic_consume_iterator() =
default;
304 constexpr basic_consume_iterator(basic_consume_iterator
const & rhs) =
default;
305 constexpr basic_consume_iterator(basic_consume_iterator && rhs) =
default;
306 constexpr basic_consume_iterator & operator=(basic_consume_iterator
const & rhs) =
default;
307 constexpr basic_consume_iterator & operator=(basic_consume_iterator && rhs) =
default;
308 ~basic_consume_iterator() =
default;
311 basic_consume_iterator(base_base_t it,
313 sentinel_type sen) noexcept(noexcept(base_t{it})) :
316 if ((*this->this_to_base() != stored_end) && fun(**
this))
318 at_end_gracefully =
true;
328 using difference_type = std::iter_difference_t<base_base_t>;
329 using value_type = std::iter_value_t<base_base_t>;
330 using reference = std::iter_reference_t<base_base_t>;
331 using pointer = detail::iter_pointer_t<base_base_t>;
340 basic_consume_iterator & operator++()
341 noexcept(noexcept(++
std::declval<base_t &>()) &&
342 noexcept(
std::declval<base_base_t &>() !=
std::declval<sentinel_type &>()) &&
343 noexcept(fun(
std::declval<reference>())))
345 base_t::operator++();
347 while ((*this->this_to_base() != stored_end) && fun(**
this))
349 at_end_gracefully =
true;
350 base_t::operator++();
357 basic_consume_iterator operator++(
int)
358 noexcept(noexcept(++std::declval<basic_consume_iterator &>()) &&
359 std::is_nothrow_copy_constructible_v<basic_consume_iterator>)
361 basic_consume_iterator cpy{*
this};
371 bool operator==(sentinel_type
const & rhs)
const
372 noexcept(!or_throw &&
373 noexcept(std::declval<base_base_t &>() != std::declval<sentinel_type &>()) &&
374 noexcept(fun(std::declval<reference>())))
376 if (at_end_gracefully)
379 if (*this->this_to_base() == rhs)
381 if constexpr (or_throw)
382 throw unexpected_end_of_input{
"Reached end of input before functor evaluated to true."};
391 friend bool operator==(sentinel_type
const & lhs, basic_consume_iterator
const & rhs)
392 noexcept(noexcept(rhs == lhs))
398 bool operator!=(sentinel_type
const & rhs)
const
399 noexcept(noexcept(std::declval<basic_consume_iterator &>() == rhs))
401 return !(*
this == rhs);
405 friend bool operator!=(sentinel_type
const & lhs, basic_consume_iterator
const & rhs)
406 noexcept(noexcept(rhs != lhs))
414 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
415 template <
bool is_const_range>
416 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_sentinel
422 using urng_sentinel_type = std::ranges::sentinel_t<urng_base_type>;
429 urng_sentinel_type urng_sentinel{};
438 basic_sentinel() =
default;
439 basic_sentinel(basic_sentinel
const &) =
default;
440 basic_sentinel(basic_sentinel &&) =
default;
441 basic_sentinel & operator=(basic_sentinel
const &) =
default;
442 basic_sentinel & operator=(basic_sentinel &&) =
default;
443 ~basic_sentinel() =
default;
449 explicit basic_sentinel(urng_sentinel_type urng_sentinel, predicate_ref_t predicate) :
450 urng_sentinel{
std::
move(urng_sentinel)},
455 basic_sentinel(basic_sentinel<!is_const_range> other)
456 requires is_const_range && std::convertible_to<std::ranges::sentinel_t<urng_t>, urng_sentinel_type>
457 : urng_sentinel{
std::move(other.urng_sentinel)},
458 predicate{other.predicate}
467 template <
typename rng_t>
468 friend bool operator==(basic_iterator<rng_t>
const & lhs, basic_sentinel
const & rhs)
471 if (lhs.base() == rhs.urng_sentinel)
473 if constexpr (or_throw)
474 throw unexpected_end_of_input{
"Reached end of input before functor evaluated to true."};
479 return rhs.predicate(*lhs);
483 template <
typename rng_t>
484 friend bool operator==(basic_sentinel
const & lhs, basic_iterator<rng_t>
const & rhs)
490 template <
typename rng_t>
491 friend bool operator!=(basic_iterator<rng_t>
const & lhs, basic_sentinel
const & rhs)
493 return !(lhs == rhs);
497 template <
typename rng_t>
498 friend bool operator!=(basic_sentinel
const & lhs, basic_iterator<rng_t>
const & rhs)
512 template <
bool or_throw,
bool and_consume>
516 template <
typename fun_t>
517 constexpr
auto operator()(fun_t && fun)
const
519 return adaptor_from_functor{*
this, std::forward<fun_t>(fun)};
529 template <std::ranges::viewable_range urng_t,
typename fun_t>
530 constexpr
auto operator()(urng_t && urange, fun_t && fun)
const
532 return view_take_until<std::views::all_t<urng_t>, fun_t, or_throw, and_consume>
534 std::views::all(std::forward<urng_t>(urange)),
535 std::forward<fun_t>(fun)
610 inline auto constexpr
take_until = detail::take_until_fn<false, false>{};
Adaptations of algorithms from the Ranges TS.
Provides various transformation traits for use on iterators.
::ranges::semiregular_box_t semiregular_box_t
Utility transformation trait to get a wrapper type that models std::semiregular. Imported from ranges...
Definition: semiregular_box.hpp:35
constexpr auto take_until_or_throw
A view adaptor that returns elements from the underlying range until the functor evaluates to true (t...
Definition: take_until.hpp:624
constexpr auto take_until
A view adaptor that returns elements from the underlying range until the functor evaluates to true (o...
Definition: take_until.hpp:610
constexpr auto take_until_or_throw_and_consume
A view adaptor that returns elements from the underlying range until the functor evaluates to true (t...
Definition: take_until.hpp:652
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
constexpr auto take_until_and_consume
A view adaptor that returns elements from the underlying range until the functor evaluates to true (o...
Definition: take_until.hpp:638
Provides the seqan3::detail::inherited_iterator_base template.
Specifies requirements of an input range type for which the const version of that type satisfies the ...
Provides exceptions used in the I/O module.
Provides C++20 additions to the <iterator> header.
The SeqAn namespace for views.
Definition: view_iota_simd.hpp:218
SeqAn specific customisations in the standard namespace.
Additional non-standard concepts for ranges.
Adaptations of concepts from the standard library.
Provides various transformation traits used by the range module.
Adaptations of concepts from the Ranges TS.
Provides seqan3::semiregular_box.
Provides C++20 additions to the type_traits header.