| 140 | // The initiating function for the asynchronous operation. |
| 141 | template <boost::asio::completion_token_for<void(std::string)> CompletionToken> |
| 142 | auto async_read_input(const std::string& prompt, CompletionToken&& token) |
| 143 | { |
| 144 | // Define a function object that contains the code to launch the asynchronous |
| 145 | // operation. This is passed the concrete completion handler, followed by any |
| 146 | // additional arguments that were passed through the call to async_initiate. |
| 147 | auto init = []( |
| 148 | boost::asio::completion_handler_for<void(std::string)> auto handler, |
| 149 | const std::string& prompt) |
| 150 | { |
| 151 | // The body of the initiation function object creates the long-lived state |
| 152 | // and passes it to the C-based API, along with the function pointer. |
| 153 | using state_type = read_input_state<decltype(handler)>; |
| 154 | read_input(prompt.c_str(), &state_type::callback, |
| 155 | state_type::create(std::move(handler))); |
| 156 | }; |
| 157 | |
| 158 | // The async_initiate function is used to transform the supplied completion |
| 159 | // token to the completion handler. When calling this function we explicitly |
| 160 | // specify the completion signature of the operation. We must also return the |
| 161 | // result of the call since the completion token may produce a return value, |
| 162 | // such as a future. |
| 163 | return boost::asio::async_initiate<CompletionToken, void(std::string)>( |
| 164 | init, // First, pass the function object that launches the operation, |
| 165 | token, // then the completion token that will be transformed to a handler, |
| 166 | prompt); // and, finally, any additional arguments to the function object. |
| 167 | } |
| 168 | |
| 169 | //------------------------------------------------------------------------------ |
| 170 | |