5 // Copyright (c) 2003-2020 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 // Disable autolinking for unit tests.
12 #if !defined(BOOST_ALL_NO_LIB)
13 #define BOOST_ALL_NO_LIB 1
14 #endif // !defined(BOOST_ALL_NO_LIB)
16 // Test that header file is self-contained.
17 #include <boost/asio/compose.hpp>
19 #include "unit_test.hpp"
21 #include <boost/asio/io_context.hpp>
22 #include <boost/asio/post.hpp>
24 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
25 # include <boost/bind/bind.hpp>
26 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
27 # include <functional>
28 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
30 //------------------------------------------------------------------------------
32 class impl_0_completion_args
35 explicit impl_0_completion_args(boost::asio::io_context
& ioc
)
41 template <typename Self
>
42 void operator()(Self
& self
)
48 boost::asio::post(ioc_
, BOOST_ASIO_MOVE_CAST(Self
)(self
));
59 boost::asio::io_context
& ioc_
;
60 enum { starting
, posting
} state_
;
63 template <typename CompletionToken
>
64 BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken
, void())
65 async_0_completion_args(boost::asio::io_context
& ioc
,
66 BOOST_ASIO_MOVE_ARG(CompletionToken
) token
)
68 return boost::asio::async_compose
<CompletionToken
, void()>(
69 impl_0_completion_args(ioc
), token
);
72 void compose_0_args_handler(int* count
)
77 struct compose_0_args_lvalue_handler
87 void compose_0_completion_args_test()
89 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
90 namespace bindns
= boost
;
91 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
92 namespace bindns
= std
;
93 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
95 boost::asio::io_context ioc
;
98 async_0_completion_args(ioc
, bindns::bind(&compose_0_args_handler
, &count
));
100 // No handlers can be called until run() is called.
101 BOOST_ASIO_CHECK(!ioc
.stopped());
102 BOOST_ASIO_CHECK(count
== 0);
106 // The run() call will not return until all work has finished.
107 BOOST_ASIO_CHECK(ioc
.stopped());
108 BOOST_ASIO_CHECK(count
== 1);
113 compose_0_args_lvalue_handler lvalue_handler
= { &count
};
114 async_0_completion_args(ioc
, lvalue_handler
);
116 // No handlers can be called until run() is called.
117 BOOST_ASIO_CHECK(!ioc
.stopped());
118 BOOST_ASIO_CHECK(count
== 0);
122 // The run() call will not return until all work has finished.
123 BOOST_ASIO_CHECK(ioc
.stopped());
124 BOOST_ASIO_CHECK(count
== 1);
127 //------------------------------------------------------------------------------
129 class impl_1_completion_arg
132 explicit impl_1_completion_arg(boost::asio::io_context
& ioc
)
138 template <typename Self
>
139 void operator()(Self
& self
)
145 boost::asio::post(ioc_
, BOOST_ASIO_MOVE_CAST(Self
)(self
));
156 boost::asio::io_context
& ioc_
;
157 enum { starting
, posting
} state_
;
160 template <typename CompletionToken
>
161 BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken
, void(int))
162 async_1_completion_arg(boost::asio::io_context
& ioc
,
163 BOOST_ASIO_MOVE_ARG(CompletionToken
) token
)
165 return boost::asio::async_compose
<CompletionToken
, void(int)>(
166 impl_1_completion_arg(ioc
), token
);
169 void compose_1_arg_handler(int* count
, int* result_out
, int result
)
172 *result_out
= result
;
175 struct compose_1_arg_lvalue_handler
180 void operator()(int result
)
183 *result_out_
= result
;
187 void compose_1_completion_arg_test()
189 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
190 namespace bindns
= boost
;
191 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
192 namespace bindns
= std
;
193 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
194 using bindns::placeholders::_1
;
196 boost::asio::io_context ioc
;
200 async_1_completion_arg(ioc
,
201 bindns::bind(&compose_1_arg_handler
, &count
, &result
, _1
));
203 // No handlers can be called until run() is called.
204 BOOST_ASIO_CHECK(!ioc
.stopped());
205 BOOST_ASIO_CHECK(count
== 0);
206 BOOST_ASIO_CHECK(result
== 0);
210 // The run() call will not return until all work has finished.
211 BOOST_ASIO_CHECK(ioc
.stopped());
212 BOOST_ASIO_CHECK(count
== 1);
213 BOOST_ASIO_CHECK(result
== 42);
219 compose_1_arg_lvalue_handler lvalue_handler
= { &count
, &result
};
220 async_1_completion_arg(ioc
, lvalue_handler
);
222 // No handlers can be called until run() is called.
223 BOOST_ASIO_CHECK(!ioc
.stopped());
224 BOOST_ASIO_CHECK(count
== 0);
225 BOOST_ASIO_CHECK(result
== 0);
229 // The run() call will not return until all work has finished.
230 BOOST_ASIO_CHECK(ioc
.stopped());
231 BOOST_ASIO_CHECK(count
== 1);
232 BOOST_ASIO_CHECK(result
== 42);
235 //------------------------------------------------------------------------------
237 BOOST_ASIO_TEST_SUITE
240 BOOST_ASIO_TEST_CASE(compose_0_completion_args_test
)
241 BOOST_ASIO_TEST_CASE(compose_1_completion_arg_test
)