31 namespace seqan3::detail
51 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
52 class view_take_until :
public std::ranges::view_interface<view_take_until<urng_t, fun_t, or_throw, and_consume>>
56 static_assert(std::invocable<fun_t, std::ranges::range_reference_t<urng_t>>,
57 "The functor type for views::take_until must model"
58 "std::invocable<fun_t, std::ranges::range_reference_t<urng_t>>.");
59 static_assert(std::convertible_to<
std::result_of_t<fun_t&&(std::ranges::range_reference_t<urng_t>)>,
bool>,
60 "The result type of the functor for views::take_until must be a boolean.");
66 ranges::semiregular_t<fun_t> fun;
70 std::regular_invocable<fun_t, std::ranges::range_reference_t<urng_t>>;
72 template <
typename rng_t>
75 template <
bool is_const_range>
78 template <
typename rng_t>
79 class basic_consume_iterator;
87 basic_consume_iterator<urng_t>,
88 basic_iterator<urng_t>>;
91 using const_iterator = basic_iterator<urng_t const>;
98 view_take_until() =
default;
99 constexpr view_take_until(view_take_until
const & rhs) =
default;
100 constexpr view_take_until(view_take_until && rhs) =
default;
101 constexpr view_take_until & operator=(view_take_until
const & rhs) =
default;
102 constexpr view_take_until & operator=(view_take_until && rhs) =
default;
103 ~view_take_until() =
default;
109 view_take_until(urng_t _urange, fun_t _fun)
118 template <std::ranges::viewable_range rng_t>
120 requires std::constructible_from<rng_t, std::views::all_t<rng_t>>
122 view_take_until(rng_t && _urange, fun_t _fun)
143 iterator
begin() noexcept
145 return {
std::ranges::begin(urange),
static_cast<fun_t &
>(fun), std::ranges::end(urange)};
149 const_iterator
begin() const noexcept
150 requires const_iterable
152 return {
std::ranges::cbegin(urange),
static_cast<fun_t
const &
>(fun), std::ranges::cend(urange)};
170 if constexpr (and_consume && !std::ranges::forward_range<urng_t>)
171 return std::ranges::end(urange);
173 return basic_sentinel<false>{std::ranges::end(urange), fun};
177 auto end() const noexcept
178 requires const_iterable
180 if constexpr (and_consume && !std::ranges::forward_range<urng_t>)
181 return std::ranges::cend(urange);
183 return basic_sentinel<true>{std::ranges::cend(urange),
static_cast<fun_t
const &
>(fun)};
190 template <
typename urng_t,
typename fun_t,
bool or_throw = false,
bool and_consume = false>
191 view_take_until(urng_t &&, fun_t) -> view_take_until<std::views::all_t<urng_t>, fun_t, or_throw, and_consume>;
195 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
196 template <
typename rng_t>
197 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_iterator :
198 public inherited_iterator_base<basic_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
202 using base_base_t = std::ranges::iterator_t<rng_t>;
204 using base_t = inherited_iterator_base<basic_iterator, std::ranges::iterator_t<rng_t>>;
206 using sentinel_type = std::ranges::sentinel_t<rng_t>;
219 constexpr basic_iterator() =
default;
220 constexpr basic_iterator(basic_iterator
const & rhs) =
default;
221 constexpr basic_iterator(basic_iterator && rhs) =
default;
222 constexpr basic_iterator & operator=(basic_iterator
const & rhs) =
default;
223 constexpr basic_iterator & operator=(basic_iterator && rhs) =
default;
224 ~basic_iterator() =
default;
227 basic_iterator(base_base_t it) noexcept(noexcept(base_t{it})) :
232 basic_iterator(base_base_t it,
234 sentinel_type ) noexcept(noexcept(base_t{it})) :
235 base_t{
std::
move(it)}, fun{_fun}
251 using pointer = detail::iter_pointer_t<base_base_t>;
253 using iterator_category = detail::iterator_category_tag_t<base_base_t>;
255 using iterator_concept = detail::iterator_concept_tag_t<base_base_t>;
261 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
262 template <
typename rng_t>
263 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_consume_iterator :
264 public inherited_iterator_base<basic_consume_iterator<rng_t>, std::ranges::iterator_t<rng_t>>
268 using base_base_t = std::ranges::iterator_t<rng_t>;
270 using base_t = inherited_iterator_base<basic_consume_iterator, std::ranges::iterator_t<rng_t>>;
280 using sentinel_type = std::ranges::sentinel_t<rng_t>;
283 sentinel_type stored_end;
286 bool at_end_gracefully =
false;
293 constexpr basic_consume_iterator() =
default;
294 constexpr basic_consume_iterator(basic_consume_iterator
const & rhs) =
default;
295 constexpr basic_consume_iterator(basic_consume_iterator && rhs) =
default;
296 constexpr basic_consume_iterator & operator=(basic_consume_iterator
const & rhs) =
default;
297 constexpr basic_consume_iterator & operator=(basic_consume_iterator && rhs) =
default;
298 ~basic_consume_iterator() =
default;
301 basic_consume_iterator(base_base_t it,
303 sentinel_type sen) noexcept(noexcept(base_t{it})) :
306 if ((this->base() != stored_end) && fun(**
this))
308 at_end_gracefully =
true;
321 using pointer = detail::iter_pointer_t<base_base_t>;
330 basic_consume_iterator & operator++()
331 noexcept(noexcept(++
std::declval<base_t &>()) &&
332 noexcept(
std::declval<base_base_t &>() !=
std::declval<sentinel_type &>()) &&
333 noexcept(fun(
std::declval<reference>())))
335 base_t::operator++();
337 while ((this->base() != stored_end) && fun(**
this))
339 at_end_gracefully =
true;
340 base_t::operator++();
347 basic_consume_iterator operator++(
int)
348 noexcept(noexcept(++std::declval<basic_consume_iterator &>()) &&
349 std::is_nothrow_copy_constructible_v<basic_consume_iterator>)
351 basic_consume_iterator cpy{*
this};
361 bool operator==(sentinel_type
const & rhs)
const
362 noexcept(!or_throw &&
363 noexcept(std::declval<base_base_t &>() != std::declval<sentinel_type &>()) &&
364 noexcept(fun(std::declval<reference>())))
366 if (at_end_gracefully)
369 if (this->base() == rhs)
371 if constexpr (or_throw)
372 throw unexpected_end_of_input{
"Reached end of input before functor evaluated to true."};
381 friend bool operator==(sentinel_type
const & lhs, basic_consume_iterator
const & rhs)
382 noexcept(noexcept(rhs == lhs))
388 bool operator!=(sentinel_type
const & rhs)
const
389 noexcept(noexcept(std::declval<basic_consume_iterator &>() == rhs))
391 return !(*
this == rhs);
395 friend bool operator!=(sentinel_type
const & lhs, basic_consume_iterator
const & rhs)
396 noexcept(noexcept(rhs != lhs))
404 template <std::ranges::view urng_t,
typename fun_t,
bool or_throw,
bool and_consume>
405 template <
bool is_const_range>
406 class view_take_until<urng_t, fun_t, or_throw, and_consume>::basic_sentinel
412 using urng_sentinel_type = std::ranges::sentinel_t<urng_base_type>;
419 urng_sentinel_type urng_sentinel{};
428 basic_sentinel() =
default;
429 basic_sentinel(basic_sentinel
const &) =
default;
430 basic_sentinel(basic_sentinel &&) =
default;
431 basic_sentinel & operator=(basic_sentinel
const &) =
default;
432 basic_sentinel & operator=(basic_sentinel &&) =
default;
433 ~basic_sentinel() =
default;
439 explicit basic_sentinel(urng_sentinel_type urng_sentinel, predicate_ref_t predicate) :
440 urng_sentinel{
std::
move(urng_sentinel)},
445 basic_sentinel(basic_sentinel<!is_const_range> other)
446 requires is_const_range && std::convertible_to<std::ranges::sentinel_t<urng_t>, urng_sentinel_type>
447 : urng_sentinel{
std::move(other.urng_sentinel)},
448 predicate{other.predicate}
457 template <
typename rng_t>
458 friend bool operator==(basic_iterator<rng_t>
const & lhs, basic_sentinel
const & rhs)
461 if (lhs.base() == rhs.urng_sentinel)
463 if constexpr (or_throw)
464 throw unexpected_end_of_input{
"Reached end of input before functor evaluated to true."};
469 return rhs.predicate(*lhs);
473 template <
typename rng_t>
474 friend bool operator==(basic_sentinel
const & lhs, basic_iterator<rng_t>
const & rhs)
480 template <
typename rng_t>
481 friend bool operator!=(basic_iterator<rng_t>
const & lhs, basic_sentinel
const & rhs)
483 return !(lhs == rhs);
487 template <
typename rng_t>
488 friend bool operator!=(basic_sentinel
const & lhs, basic_iterator<rng_t>
const & rhs)
502 template <
bool or_throw,
bool and_consume>
506 template <
typename fun_t>
507 constexpr
auto operator()(fun_t && fun)
const
509 return adaptor_from_functor{*
this, std::forward<fun_t>(fun)};
519 template <std::ranges::viewable_range urng_t,
typename fun_t>
520 constexpr
auto operator()(urng_t && urange, fun_t && fun)
const
522 return view_take_until<std::views::all_t<urng_t>, fun_t, or_throw, and_consume>
524 std::views::all(std::forward<urng_t>(urange)),
525 std::forward<fun_t>(fun)
600 inline auto constexpr
take_until = detail::take_until_fn<false, false>{};
Adaptations of algorithms from the Ranges TS.
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.hpp:614
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:600
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:642
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:70
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:628
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 various transformation traits for use on iterators.
Provides C++20 additions to the <iterator> header.
The SeqAn namespace for views.
Definition: async_input_buffer.hpp:343
SeqAn specific customisations in the standard namespace.
Additional non-standard concepts for ranges.
Adaptations of concepts from the standard library.
Adaptations of concepts from the Ranges TS.
Provides seqan3::semiregular_box.
Provides C++20 additions to the type_traits header.