Commit 5498fe5e authored by Dominik Charousset's avatar Dominik Charousset

Add missing do_on_next operator

parent 19a141fc
...@@ -183,6 +183,12 @@ public: ...@@ -183,6 +183,12 @@ public:
return transform(do_on_error_step<T, F>{std::move(f)}); return transform(do_on_error_step<T, F>{std::move(f)});
} }
/// Registers a callback that runs on `on_next`.
template <class F>
auto do_on_next(F f) {
return transform(do_on_next_step<F>{std::move(f)});
}
/// Registers a callback that runs on `on_complete` or `on_error`. /// Registers a callback that runs on `on_complete` or `on_error`.
template <class F> template <class F>
auto do_finally(F f) { auto do_finally(F f) {
...@@ -1224,11 +1230,17 @@ public: ...@@ -1224,11 +1230,17 @@ public:
.transform(do_on_error_step<output_type, F>{std::move(f)}); .transform(do_on_error_step<output_type, F>{std::move(f)});
} }
template <class F>
auto do_on_next(F f) && {
return std::move(*this).transform(do_on_next_step<F>{std::move(f)});
}
template <class F> template <class F>
auto do_finally(F f) && { auto do_finally(F f) && {
return std::move(*this) // return std::move(*this) //
.transform(do_finally_step<output_type, F>{std::move(f)}); .transform(do_finally_step<output_type, F>{std::move(f)});
} }
auto on_error_complete() { auto on_error_complete() {
return std::move(*this) // return std::move(*this) //
.transform(on_error_complete_step<output_type>{}); .transform(on_error_complete_step<output_type>{});
......
...@@ -154,6 +154,47 @@ struct flat_map_optional_step { ...@@ -154,6 +154,47 @@ struct flat_map_optional_step {
} }
}; };
template <class Fn>
class do_on_next_step {
public:
using trait = detail::get_callable_trait_t<Fn>;
static_assert(trait::num_args == 1,
"do_on_next functions must take exactly one argument");
using input_type = std::decay_t<detail::tl_head_t<typename trait::arg_types>>;
using output_type = input_type;
explicit do_on_next_step(Fn fn) : fn_(std::move(fn)) {
// nop
}
do_on_next_step(do_on_next_step&&) = default;
do_on_next_step(const do_on_next_step&) = default;
do_on_next_step& operator=(do_on_next_step&&) = default;
do_on_next_step& operator=(const do_on_next_step&) = default;
template <class Next, class... Steps>
bool on_next(const input_type& item, Next& next, Steps&... steps) {
fn_(item);
return next.on_next(item, steps...);
}
template <class Next, class... Steps>
void on_complete(Next& next, Steps&... steps) {
next.on_complete(steps...);
}
template <class Next, class... Steps>
void on_error(const error& what, Next& next, Steps&... steps) {
next.on_error(what, steps...);
}
private:
Fn fn_;
};
template <class T, class Fn> template <class T, class Fn>
struct do_on_complete_step { struct do_on_complete_step {
using input_type = T; using input_type = T;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment