Skip to content

Instantly share code, notes, and snippets.

@cbodley
Created March 13, 2018 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbodley/62c96eefcda46be50c56ca2e0ed84b66 to your computer and use it in GitHub Desktop.
Save cbodley/62c96eefcda46be50c56ca2e0ed84b66 to your computer and use it in GitHub Desktop.
#include <boost/asio.hpp>
#define BOOST_COROUTINES_NO_DEPRECATION_WARNING
#include <boost/asio/spawn.hpp>
#include <iostream>
#include <memory>
using boost::system::error_code;
// use a move-only result type
using result_type = std::unique_ptr<int>;
template <typename Handler>
class completion_handler {
Handler handler;
error_code ec;
result_type result;
public:
completion_handler(Handler&& handler, error_code ec, result_type&& result)
: handler(std::move(handler)), ec(ec), result(std::move(result))
{}
void operator()() {
handler(ec, std::move(result));
}
};
// initiating function that returns a move-only result
template <typename ExecutionContext, typename CompletionToken,
typename Signature = void(error_code, result_type&&)>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
async_get_result(ExecutionContext& ctx, CompletionToken&& token)
{
boost::asio::async_completion<CompletionToken, Signature> init(token);
auto& handler = init.completion_handler;
auto ex1 = ctx.get_executor();
auto ex2 = boost::asio::get_associated_executor(handler, ex1);
auto alloc2 = boost::asio::get_associated_allocator(handler);
auto f = completion_handler(std::move(handler), error_code{},
std::make_unique<int>(42));
ex2.post(std::move(f), alloc2);
return init.result.get();
}
int main(int argc, char **argv)
{
boost::asio::io_context context;
boost::asio::spawn(context, [&] (boost::asio::yield_context yield) {
auto result = async_get_result(context, yield);
std::cout << *result << std::endl;
});
async_get_result(context, [] (error_code ec, result_type&& result) {
std::cout << *result << std::endl;
});
auto result = async_get_result(context, boost::asio::use_future);
std::cout << *result.get() << std::endl;
context.run();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment