]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/example/cpp11/operations/composed_1.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / asio / example / cpp11 / operations / composed_1.cpp
CommitLineData
92f5a8d4
TL
1//
2// composed_1.cpp
3// ~~~~~~~~~~~~~~
4//
1e59de90 5// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
92f5a8d4
TL
6//
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)
9//
10
11#include <boost/asio/io_context.hpp>
12#include <boost/asio/ip/tcp.hpp>
13#include <boost/asio/use_future.hpp>
14#include <boost/asio/write.hpp>
15#include <cstring>
16#include <iostream>
17#include <string>
18#include <type_traits>
19#include <utility>
20
21using boost::asio::ip::tcp;
22
23//------------------------------------------------------------------------------
24
25// This is the simplest example of a composed asynchronous operation, where we
26// simply repackage an existing operation. The asynchronous operation
27// requirements are met by delegating responsibility to the underlying
28// operation.
29
30template <typename CompletionToken>
31auto async_write_message(tcp::socket& socket,
32 const char* message, CompletionToken&& token)
33 // The return type of the initiating function is deduced from the combination
34 // of CompletionToken type and the completion handler's signature. When the
35 // completion token is a simple callback, the return type is void. However,
36 // when the completion token is boost::asio::yield_context (used for stackful
37 // coroutines) the return type would be std::size_t, and when the completion
38 // token is boost::asio::use_future it would be std::future<std::size_t>.
39 -> typename boost::asio::async_result<
40 typename std::decay<CompletionToken>::type,
41 void(boost::system::error_code, std::size_t)>::return_type
42{
43 // When delegating to the underlying operation we must take care to perfectly
44 // forward the completion token. This ensures that our operation works
45 // correctly with move-only function objects as callbacks, as well as other
46 // completion token types.
47 return boost::asio::async_write(socket,
48 boost::asio::buffer(message, std::strlen(message)),
49 std::forward<CompletionToken>(token));
50}
51
52//------------------------------------------------------------------------------
53
54void test_callback()
55{
56 boost::asio::io_context io_context;
57
58 tcp::acceptor acceptor(io_context, {tcp::v4(), 55555});
59 tcp::socket socket = acceptor.accept();
60
61 // Test our asynchronous operation using a lambda as a callback.
62 async_write_message(socket, "Testing callback\r\n",
63 [](const boost::system::error_code& error, std::size_t n)
64 {
65 if (!error)
66 {
67 std::cout << n << " bytes transferred\n";
68 }
69 else
70 {
71 std::cout << "Error: " << error.message() << "\n";
72 }
73 });
74
75 io_context.run();
76}
77
78//------------------------------------------------------------------------------
79
80void test_future()
81{
82 boost::asio::io_context io_context;
83
84 tcp::acceptor acceptor(io_context, {tcp::v4(), 55555});
85 tcp::socket socket = acceptor.accept();
86
87 // Test our asynchronous operation using the use_future completion token.
88 // This token causes the operation's initiating function to return a future,
89 // which may be used to synchronously wait for the result of the operation.
90 std::future<std::size_t> f = async_write_message(
91 socket, "Testing future\r\n", boost::asio::use_future);
92
93 io_context.run();
94
95 try
96 {
97 // Get the result of the operation.
98 std::size_t n = f.get();
99 std::cout << n << " bytes transferred\n";
100 }
101 catch (const std::exception& e)
102 {
103 std::cout << "Error: " << e.what() << "\n";
104 }
105}
106
107//------------------------------------------------------------------------------
108
109int main()
110{
111 test_callback();
112 test_future();
113}