30 namespace seqan3::detail
50 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
51 class view_take_until :
public std::ranges::view_interface<view_take_until<urng_t, fun_t, or_throw, and_consume>>
55 static_assert(std::invocable<fun_t, std::ranges::range_reference_t<urng_t>>,
56 "The functor type for detail::take_until must model"
57 "std::invocable<fun_t, std::ranges::range_reference_t<urng_t>>.");
58 static_assert(std::convertible_to<
std::result_of_t<fun_t&&(std::ranges::range_reference_t<urng_t>)>,
bool>,
59 "The result type of the functor for detail::take_until must be a boolean.");
65 ranges::semiregular_t<fun_t> fun;
69 std::regular_invocable<fun_t, std::ranges::range_reference_t<urng_t>>;
71 template <
typename rng_t>
74 template <
bool is_const_range>
77 template <
typename rng_t>
78 class basic_consume_iterator;
86 basic_consume_iterator<urng_t>,
87 basic_iterator<urng_t>>;
90 using const_iterator = basic_iterator<urng_t const>;
97 view_take_until() =
default;
98 constexpr view_take_until(view_take_until
const & rhs) =
default;
99 constexpr view_take_until(view_take_until && rhs) =
default;
100 constexpr view_take_until & operator=(view_take_until
const & rhs) =
default;
101 constexpr view_take_until & operator=(view_take_until && rhs) =
default;
102 ~view_take_until() =
default;
108 view_take_until(urng_t _urange, fun_t _fun)
117 template <std::ranges::viewable_range rng_t>
119 requires std::constructible_from<rng_t, std::views::all_t<rng_t>>
121 view_take_until(rng_t && _urange, fun_t _fun)
142 iterator
begin() noexcept
144 return {
std::ranges::begin(urange),
static_cast<fun_t &
>(fun), std::ranges::end(urange)};
148 const_iterator
begin() const noexcept
149 requires const_iterable
151 return {
std::ranges::cbegin(urange),
static_cast<fun_t
const &
>(fun), std::ranges::cend(urange)};
169 if constexpr (and_consume && !std::ranges::forward_range<urng_t>)
170 return std::ranges::end(urange);
172 return basic_sentinel<false>{std::ranges::end(urange), fun};
176 auto end() const noexcept
177 requires const_iterable
179 if constexpr (and_consume && !std::ranges::forward_range<urng_t>)
180 return std::ranges::cend(urange);
182 return basic_sentinel<true>{std::ranges::cend(urange),
static_cast<fun_t
const &
>(fun)};
189 template <
typename urng_t,
typename fun_t,
bool or_throw = false,
bool and_consume = false>
190 view_take_until(urng_t &&, fun_t) -> view_take_until<std::views::all_t<urng_t>, fun_t, or_throw, and_consume>;
194 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
195 template <
typename rng_t>
196 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_iterator :
197 public inherited_iterator_base<basic_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
201 using base_base_t = std::ranges::iterator_t<rng_t>;
203 using base_t = inherited_iterator_base<basic_iterator, std::ranges::iterator_t<rng_t>>;
205 using sentinel_type = std::ranges::sentinel_t<rng_t>;
218 constexpr basic_iterator() =
default;
219 constexpr basic_iterator(basic_iterator
const & rhs) =
default;
220 constexpr basic_iterator(basic_iterator && rhs) =
default;
221 constexpr basic_iterator & operator=(basic_iterator
const & rhs) =
default;
222 constexpr basic_iterator & operator=(basic_iterator && rhs) =
default;
223 ~basic_iterator() =
default;
226 basic_iterator(base_base_t it) noexcept(noexcept(base_t{it})) :
231 basic_iterator(base_base_t it,
233 sentinel_type ) noexcept(noexcept(base_t{it})) :
234 base_t{
std::
move(it)}, fun{_fun}
241 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
242 template <
typename rng_t>
243 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_consume_iterator :
244 public inherited_iterator_base<basic_consume_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
248 using base_base_t = std::ranges::iterator_t<rng_t>;
250 using base_t = inherited_iterator_base<basic_consume_iterator, std::ranges::iterator_t<rng_t>>;
260 using sentinel_type = std::ranges::sentinel_t<rng_t>;
263 sentinel_type stored_end;
266 bool at_end_gracefully =
false;
273 constexpr basic_consume_iterator() =
default;
274 constexpr basic_consume_iterator(basic_consume_iterator
const & rhs) =
default;
275 constexpr basic_consume_iterator(basic_consume_iterator && rhs) =
default;
276 constexpr basic_consume_iterator & operator=(basic_consume_iterator
const & rhs) =
default;
277 constexpr basic_consume_iterator & operator=(basic_consume_iterator && rhs) =
default;
278 ~basic_consume_iterator() =
default;
281 basic_consume_iterator(base_base_t it,
283 sentinel_type sen) noexcept(noexcept(base_t{it})) :
286 if ((this->base() != stored_end) && fun(**
this))
288 at_end_gracefully =
true;
301 using pointer = detail::iter_pointer_t<base_base_t>;
310 basic_consume_iterator & operator++()
311 noexcept(noexcept(++
std::declval<base_t &>()) &&
312 noexcept(
std::declval<base_base_t &>() !=
std::declval<sentinel_type &>()) &&
313 noexcept(fun(
std::declval<reference>())))
315 base_t::operator++();
317 while ((this->base() != stored_end) && fun(**
this))
319 at_end_gracefully =
true;
320 base_t::operator++();
327 basic_consume_iterator operator++(
int)
328 noexcept(noexcept(++std::declval<basic_consume_iterator &>()) &&
329 std::is_nothrow_copy_constructible_v<basic_consume_iterator>)
331 basic_consume_iterator cpy{*
this};
341 bool operator==(sentinel_type
const & rhs)
const
342 noexcept(!or_throw &&
343 noexcept(std::declval<base_base_t &>() != std::declval<sentinel_type &>()) &&
344 noexcept(fun(std::declval<reference>())))
346 if (at_end_gracefully)
349 if (this->base() == rhs)
351 if constexpr (or_throw)
352 throw unexpected_end_of_input{
"Reached end of input before functor evaluated to true."};
361 friend bool operator==(sentinel_type
const & lhs, basic_consume_iterator
const & rhs)
362 noexcept(noexcept(rhs == lhs))
368 bool operator!=(sentinel_type
const & rhs)
const
369 noexcept(noexcept(std::declval<basic_consume_iterator &>() == rhs))
371 return !(*
this == rhs);
375 friend bool operator!=(sentinel_type
const & lhs, basic_consume_iterator
const & rhs)
376 noexcept(noexcept(rhs != lhs))
384 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
385 template <
bool is_const_range>
386 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_sentinel
392 using urng_sentinel_type = std::ranges::sentinel_t<urng_base_type>;
399 urng_sentinel_type urng_sentinel{};
408 basic_sentinel() =
default;
409 basic_sentinel(basic_sentinel
const &) =
default;
410 basic_sentinel(basic_sentinel &&) =
default;
411 basic_sentinel & operator=(basic_sentinel
const &) =
default;
412 basic_sentinel & operator=(basic_sentinel &&) =
default;
413 ~basic_sentinel() =
default;
419 explicit basic_sentinel(urng_sentinel_type urng_sentinel, predicate_ref_t predicate) :
420 urng_sentinel{
std::
move(urng_sentinel)},
425 basic_sentinel(basic_sentinel<!is_const_range> other)
426 requires is_const_range && std::convertible_to<std::ranges::sentinel_t<urng_t>, urng_sentinel_type>
427 : urng_sentinel{
std::move(other.urng_sentinel)},
428 predicate{other.predicate}
437 template <
typename rng_t>
438 friend bool operator==(basic_iterator<rng_t>
const & lhs, basic_sentinel
const & rhs)
441 if (lhs.base() == rhs.urng_sentinel)
443 if constexpr (or_throw)
444 throw unexpected_end_of_input{
"Reached end of input before functor evaluated to true."};
449 return rhs.predicate(*lhs);
453 template <
typename rng_t>
454 friend bool operator==(basic_sentinel
const & lhs, basic_iterator<rng_t>
const & rhs)
460 template <
typename rng_t>
461 friend bool operator!=(basic_iterator<rng_t>
const & lhs, basic_sentinel
const & rhs)
463 return !(lhs == rhs);
467 template <
typename rng_t>
468 friend bool operator!=(basic_sentinel
const & lhs, basic_iterator<rng_t>
const & rhs)
482 template <
bool or_throw,
bool and_consume>
486 template <
typename fun_t>
487 constexpr
auto operator()(fun_t && fun)
const
489 return adaptor_from_functor{*
this, std::forward<fun_t>(fun)};
499 template <std::ranges::viewable_range urng_t,
typename fun_t>
500 constexpr
auto operator()(urng_t && urange, fun_t && fun)
const
502 return view_take_until<std::views::all_t<urng_t>, fun_t, or_throw, and_consume>
504 std::views::all(std::forward<urng_t>(urange)),
505 std::forward<fun_t>(fun)
516 namespace seqan3::detail
580 inline auto constexpr
take_until = take_until_fn<false, false>{};
628 #ifdef SEQAN3_DEPRECATED_310
Provides seqan3::detail::adaptor_from_functor.
Adaptations of algorithms from the Ranges TS.
Provides the seqan3::detail::inherited_iterator_base template.
Provides various transformation traits used by the range module.
::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_view.hpp:645
constexpr auto take_until
A view adaptor that returns elements from the underlying range until the functor evaluates to true (o...
Definition: take_until_view.hpp:637
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_view.hpp:661
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:74
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_view.hpp:653
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 various transformation traits for use on iterators.
Provides C++20 additions to the <iterator> header.
The SeqAn namespace for views.
Definition: char_to.hpp:22
SeqAn specific customisations in the standard namespace.
Adaptations of concepts from the Ranges TS.
Provides seqan3::semiregular_box.
Provides C++20 additions to the type_traits header.
Additional non-standard concepts for ranges.