The composed function creates an initiation function object from a stateful
implementation. It is similar to co_composed, but for regular function objects
rather than C++20 coroutines.
For example:
struct async_echo_implementation
{
tcp::socket& socket_;
boost::asio::mutable_buffer buffer_;
enum { starting, reading, writing } state_;
template <typename Self>
void operator()(Self& self,
boost::system::error_code error,
std::size_t n)
{
switch (state_)
{
case starting:
state_ = reading;
socket_.async_read_some(
buffer_, std::move(self));
break;
case reading:
if (error)
{
self.complete(error, 0);
}
else
{
state_ = writing;
boost::asio::async_write(socket_, buffer_,
boost::asio::transfer_exactly(n),
std::move(self));
}
break;
case writing:
self.complete(error, n);
break;
}
}
};
template <typename CompletionToken>
auto async_echo(tcp::socket& socket,
boost::asio::mutable_buffer buffer,
CompletionToken&& token)
{
return boost::asio::async_initiate<CompletionToken,
void(boost::system::error_code, std::size_t)>(
boost::asio::composed(
async_echo_implementation{socket, buffer,
async_echo_implementation::starting}, socket),
token, boost::system::error_code{}, 0);
}
The async_compose function has been changed to be a thin wrapper around
composed. However, unlike async_compose, composed allows arguments to be passed
to the stateful implementation when the operation is initiated.