]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp14/operations/callback_wrapper.cpp
2 // callback_wrapper.cpp
3 // ~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #include <boost/asio.hpp>
14 //------------------------------------------------------------------------------
16 // This is a mock implementation of an API that uses a move-only function object
17 // for exposing a callback. The callback has the signature void(std::string).
19 template <typename Callback
>
20 void read_input(const std::string
& prompt
, Callback cb
)
23 [prompt
, cb
= std::move(cb
)]() mutable
25 std::cout
<< prompt
<< ": ";
28 std::getline(std::cin
, line
);
29 std::move(cb
)(std::move(line
));
33 //------------------------------------------------------------------------------
35 // This is an asynchronous operation that wraps the callback-based API.
37 // The initiating function for the asynchronous operation.
38 template <typename CompletionToken
>
39 auto async_read_input(const std::string
& prompt
, CompletionToken
&& token
)
41 // Define a function object that contains the code to launch the asynchronous
42 // operation. This is passed the concrete completion handler, followed by any
43 // additional arguments that were passed through the call to async_initiate.
44 auto init
= [](auto handler
, const std::string
& prompt
)
46 // According to the rules for asynchronous operations, we need to track
47 // outstanding work against the handler's associated executor until the
48 // asynchronous operation is complete.
49 auto work
= boost::asio::make_work_guard(handler
);
51 // Launch the operation with a callback that will receive the result and
52 // pass it through to the asynchronous operation's completion handler.
55 handler
= std::move(handler
),
56 work
= std::move(work
)
57 ](std::string result
) mutable
59 // Get the handler's associated allocator. If the handler does not
60 // specify an allocator, use the recycling allocator as the default.
61 auto alloc
= boost::asio::get_associated_allocator(
62 handler
, boost::asio::recycling_allocator
<void>());
64 // Dispatch the completion handler through the handler's associated
65 // executor, using the handler's associated allocator.
66 boost::asio::dispatch(work
.get_executor(),
67 boost::asio::bind_allocator(alloc
,
69 handler
= std::move(handler
),
70 result
= std::string(result
)
73 std::move(handler
)(result
);
78 // The async_initiate function is used to transform the supplied completion
79 // token to the completion handler. When calling this function we explicitly
80 // specify the completion signature of the operation. We must also return the
81 // result of the call since the completion token may produce a return value,
83 return boost::asio::async_initiate
<CompletionToken
, void(std::string
)>(
84 init
, // First, pass the function object that launches the operation,
85 token
, // then the completion token that will be transformed to a handler,
86 prompt
); // and, finally, any additional arguments to the function object.
89 //------------------------------------------------------------------------------
93 boost::asio::io_context io_context
;
95 // Test our asynchronous operation using a lambda as a callback. We will use
96 // an io_context to specify an associated executor.
97 async_read_input("Enter your name",
98 boost::asio::bind_executor(io_context
,
99 [](const std::string
& result
)
101 std::cout
<< "Hello " << result
<< "\n";
107 //------------------------------------------------------------------------------
111 // Test our asynchronous operation using the use_future completion token.
112 // This token causes the operation's initiating function to return a future,
113 // which may be used to synchronously wait for the result of the operation.
114 std::future
<std::string
> f
=
115 async_read_input("Enter your name", boost::asio::use_future
);
117 std::string result
= f
.get();
118 std::cout
<< "Hello " << result
<< "\n";
121 //------------------------------------------------------------------------------