Boost
C++ Libraries
...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
This is an older version of Boost and was released in 2019. The current version is 1.90.0.
Support for the Coroutines TS is provided via the awaitable
class template, the use_awaitable
completion token, and the co_spawn()
function. These facilities allow programs to implement asynchronous logic
in a synchronous manner, in conjunction with the co_await
keyword, as shown in the following example:
boost::asio::co_spawn(executor,
[socket = std::move(socket)]() mutable
{
return echo(std::move(socket));
},
boost::asio::detached);
// ...
boost::asio::awaitable<void> echo(tcp::socket socket)
{
try
{
char data[1024];
for (;;)
{
std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);
co_await async_write(socket, boost::asio::buffer(data, n), boost::asio::use_awaitable);
}
}
catch (std::exception& e)
{
std::printf("echo Exception: %s\n", e.what());
}
}
The first argument to co_spawn() is an executor
that determines the context in which the coroutine is permitted to execute.
For example, a server's per-client object may consist of multiple coroutines;
they should all run on the same strand so that no explicit
synchronisation is required.
The second argument is a nullary function object that returns a boost::asio::awaitable<R>,
where R is the type of return value produced by the coroutine.
In the above example, the coroutine returns void.
The third argument is a completion token, and this is used by co_spawn()
to produce a completion handler with signature void(std::exception_ptr,
R). This completion handler is invoked with the result of the coroutine
once it has finished. In the above example we pass a completion token type,
boost::asio::detached,
which is used to explicitly ignore the result of an asynchronous operation.
In this example the body of the coroutine is implemented in the echo
function. When the use_awaitable completion token is passed
to an asynchronous operation, the operation's initiating function returns
an awaitable that may be used with the co_await
keyword:
std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);
Where an asynchronous operation's handler signature has the form:
void handler(boost::system::error_code ec, result_type result);
the resulting type of the co_await expression is result_type.
In the async_read_some example above, this is size_t.
If the asynchronous operation fails, the error_code is converted
into a system_error exception and thrown.
Where a handler signature has the form:
void handler(boost::system::error_code ec);
the co_await expression produces a void result.
As above, an error is passed back to the coroutine as a system_error
exception.
co_spawn, detached, redirect_error, awaitable, use_awaitable_t, use_awaitable, this_coro::executor, Coroutines TS examples, Stackful Coroutines, Stackless Coroutines.