On Writing Loops in PPL and Continuation-passing Style, Part 3 -- Raymond Chen
In our previous discussion, we optimized a task-based while loop by eliminating nested shared pointers, instead requiring all the state to reside inside a caller-provided shared_ptr
, making the callable stateless. This approach simplifies the code and reduces redundancy in managing state.
On Writing Loops in PPL and Continuation-passing Style, Part 3
By Raymond Chen
From the article:
Last time, we wrote a task-based
while
loop using recursion, using ashared_ptr
to pass state, and we noted a redundancy in that we created ashared_ptr
to a lambda that in turn held ashared_ptr
.We can eliminate the nested shared pointers by requiring that all the state live inside a caller-provided
shared_ptr
, levaing the callable stateless.template<typename State> task<void> do_while_task( std::shared_ptr<State> const& state, bool (*f)(std::shared_ptr<State> const&) { return f(state).then([state, f](bool loop) { return loop ? do_while_task(state, f) : task_from_result(); }); } struct lambda_state { lambda_state(Widgets* w) : widgets(w) {} Widgets* widgets; int i = 0; }; auto state = std::make_shared<lambda_state>(widgets); do_while_task(state, [](auto&& state) { if (state->i >= 3) return task_from_result(false); return create_widget().then([state](auto widget) { state->widgets[state->i] = widget; state->i++; return true; } }).then([] { printf("Done!\n"); });We can get rid of all the
state->
prefixes by making the state be invocable.