@@ -12,7 +12,7 @@ namespace flux {
1212
1313namespace detail {
1414
15- template <sequence Base, typename Pred>
15+ template <iterable Base, typename Pred>
1616struct take_while_adaptor : inline_sequence_base<take_while_adaptor<Base, Pred>> {
1717private:
1818 Base base_;
@@ -34,19 +34,43 @@ struct take_while_adaptor : inline_sequence_base<take_while_adaptor<Base, Pred>>
3434};
3535
3636struct take_while_fn {
37- template <adaptable_sequence Seq , std::move_constructible Pred>
38- requires std::predicate<Pred&, element_t <Seq >>
37+ template <sink_iterable It , std::move_constructible Pred>
38+ requires std::predicate<Pred&, element_t <It >>
3939 [[nodiscard]]
40- constexpr auto operator ()(Seq && seq , Pred pred) const
40+ constexpr auto operator ()(It && it , Pred pred) const
4141 {
42- return take_while_adaptor<std::decay_t <Seq >, Pred>(
43- FLUX_FWD (seq ), std::move (pred));
42+ return take_while_adaptor<std::decay_t <It >, Pred>(
43+ FLUX_FWD (it ), std::move (pred));
4444 }
4545};
4646
4747} // namespace detail
4848
49- template <typename Base, typename Pred>
49+ template <iterable Base, typename Pred>
50+ struct sequence_traits <detail::take_while_adaptor<Base, Pred>>
51+ : default_sequence_traits {
52+
53+ static consteval auto element_type (auto & self)
54+ -> element_t<decltype((self.base_))>;
55+
56+ static constexpr auto iterate(auto & self, auto && iter_pred) -> bool
57+ {
58+ bool done = false ;
59+ bool res = flux::iterate (self.base_ , [&](auto && elem) {
60+ if (!std::invoke (self.pred_ , elem)) {
61+ done = true ;
62+ return false ; // break
63+ } else {
64+ return std::invoke (iter_pred, FLUX_FWD (elem));
65+ }
66+ });
67+ // Return true if take_while was exhausted
68+ return res ? res : done;
69+ }
70+
71+ };
72+
73+ template <sequence Base, typename Pred>
5074struct sequence_traits <detail::take_while_adaptor<Base, Pred>>
5175 : detail::passthrough_traits_base
5276{
@@ -57,7 +81,21 @@ struct sequence_traits<detail::take_while_adaptor<Base, Pred>>
5781 static constexpr bool is_infinite = false ;
5882
5983 using default_sequence_traits::element_type;
60- using default_sequence_traits::iterate;
84+
85+ static constexpr auto iterate(auto & self, auto && iter_pred) -> bool
86+ {
87+ bool done = false ;
88+ bool res = flux::iterate (self.base_ , [&](auto && elem) {
89+ if (!std::invoke (self.pred_ , elem)) {
90+ done = true ;
91+ return false ; // break
92+ } else {
93+ return std::invoke (iter_pred, FLUX_FWD (elem));
94+ }
95+ });
96+ // Return true if take_while was exhausted
97+ return res ? res : done;
98+ }
6199
62100 template <typename Self>
63101 static constexpr bool is_last (Self& self, cursor_t <Self> const & cur)
0 commit comments