I'd like to create an asynchronous function which takes as it's last argument boost::asio::yield_context. E.g.:
int async_meaning_of_life(asio::yield_context yield);
I'd also like to be consistent with how Asio returns error codes. That is, if the user does:
int result = async_meaning_of_life(yield);
and the function fails, then it throws the system_error
exception. But if the user does:
boost::error_code ec;
int result = async_meaning_of_life(yield[ec]);
Then - instead of throwing - the error is returned in ec
.
The problem is that when implementing the function, I can't seem to find a clean way to check whether the operator[] was used or not and set it if so. We came up with something like this:
inline void set_error(asio::yield_context yield, sys::error_code ec)
{
if (!yield.ec_) throw system_error(ec);
*(yield.ec_) = ec;
}
But that's hacky, because yield_context::ec_
is declared private (although only in the documentation).
One other way I can think of doing this is to convert the yield
object into asio::handler_type
and execute it. But this solution seems awkward at best.
Is there another way?
Asio uses
async_result
to transparently provideuse_future
,yield_context
or completion handlers in its API interfaces.¹Here's how the pattern goes:
Comprehensive Demo
Showing how to use it with with
Live On Coliru
Prints:
¹ see e.g. this excellent demonstration of how to use it to extend the library with your own async result pattern boost::asio with boost::unique_future