COROUTINES BASICS IN C++

What is a coroutine?

  • Any function that calls

    • co_return

    • co_await

    • co_yield

  • That's it.

What do they do?

  • Suspend function execution

  • Resume it from the same place

  • Automatically handle saving/restoring underlying state

struct promise;
 
struct coroutine : std::coroutine_handle<promise>
{
    using promise_type = ::promise;
};
 
struct promise
{
    coroutine get_return_object() { return {coroutine::from_promise(*this)}; }
    std::suspend_always initial_suspend() noexcept { return {}; }
    std::suspend_always final_suspend() noexcept { return {}; }
    void return_void() {}
    void unhandled_exception() {}
};

Basic promise

// When coroutine gets called, what to return
coroutine get_return_object()
{
	return {coroutine::from_promise(*this)};
}

Basic promise

// When coroutine gets called, what to do
std::suspend_always initial_suspend() noexcept
{
	return {};
}

Basic promise

// When coroutine ends (or co_returns), what to do
std::suspend_always final_suspend() noexcept
{
	return {};
}

Basic promise

// What to do if we return `void`
void return_void() {}

// What to do if there's an unhandled exception
void unhandled_exception() {}

Basic promise

coroutine foo() // Can have reference parameters, whatever, it'll work
{
    for (int i = 0; i < 10; ++i)
    {
    	std::cout << i << '\n';
        co_await std::suspend_always{};
    }
}
\\ ...

coroutine handle = foo();
while (!handle.done())
    handle.resume();

handle.destroy();

how to use

coroutine handle = foo(); // finish running foo
assert (handle.done());

handle.destroy(); // Destroy (suspended) handle, freeing coroutine memory

// handle still exists!
assert (handle);
handle.done(); // UB, dereferencing pointer
handle.destroy(); // Crash

// can be reassigned to 'nullptr' coroutine
handle = coroutine();
// Does not work like a pointer though!
assert (!handle);
handle.destroy(); // Crash

DESTRUCTION

REFER TO dOCS

  • Many more customization points

    • yield_value
    • awaitable definition
    • get_return_object_on_allocation_failure
    • and some more...

THE
END

Coroutine Basics in C++

By svalorzen

Coroutine Basics in C++

  • 97