#include <boost/asio.hpp>
#include <iostream>
template <typename Callback>
void read_input(const std::string& prompt, Callback cb)
{
std::thread(
[prompt, cb = std::move(cb)]() mutable
{
std::cout << prompt << ": ";
std::cout.flush();
std::string line;
std::getline(std::cin, line);
std::move(cb)(std::move(line));
}).detach();
}
template <typename CompletionToken>
auto async_read_input(const std::string& prompt, CompletionToken&& token)
{
auto init = [](auto handler, const std::string& prompt)
{
auto work = boost::asio::make_work_guard(handler);
read_input(prompt,
[
handler = std::move(handler),
work = std::move(work)
](std::string result) mutable
{
auto alloc = boost::asio::get_associated_allocator(
handler, boost::asio::recycling_allocator<void>());
boost::asio::dispatch(work.get_executor(),
boost::asio::bind_allocator(alloc,
[
handler = std::move(handler),
result = std::string(result)
]() mutable
{
std::move(handler)(result);
}));
});
};
return boost::asio::async_initiate<CompletionToken, void(std::string)>(
init, token, prompt); }
void test_callback()
{
boost::asio::io_context io_context;
async_read_input("Enter your name",
boost::asio::bind_executor(io_context,
[](const std::string& result)
{
std::cout << "Hello " << result << "\n";
}));
io_context.run();
}
void test_deferred()
{
boost::asio::io_context io_context;
auto op = async_read_input("Enter your name", boost::asio::deferred);
std::move(op)(
boost::asio::bind_executor(io_context,
[](const std::string& result)
{
std::cout << "Hello " << result << "\n";
}));
io_context.run();
}
void test_future()
{
std::future<std::string> f =
async_read_input("Enter your name", boost::asio::use_future);
std::string result = f.get();
std::cout << "Hello " << result << "\n";
}
int main()
{
test_callback();
test_deferred();
test_future();
}