On Writing Loops in PPL and Continuation-passing Style, Part 3 -- Raymond Chen

RaymondChen_5in-150x150.jpgIn 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 a shared_ptr to pass state, and we noted a redundancy in that we created a shared_ptr to a lambda that in turn held a shared_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.

Add a Comment

Comments are closed.

Comments (0)

There are currently no comments on this entry.