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/execution/execute.hpp>
18 #include <boost/asio/execution/sender.hpp>
19 #include <boost/asio/execution/submit.hpp>
21 #include <boost/asio/execution/invocable_archetype.hpp>
22 #include "../unit_test.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 namespace exec
= boost::asio::execution
;
36 struct const_member_execute
39 void execute(BOOST_ASIO_MOVE_ARG(F
) f
) const
41 typename
boost::asio::decay
<F
>::type
tmp(BOOST_ASIO_MOVE_CAST(F
)(f
));
46 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
53 struct execute_member
<const_member_execute
, F
>
55 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= true);
56 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
57 typedef void result_type
;
64 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
66 struct free_execute_const_executor
69 friend void execute(const free_execute_const_executor
&,
70 BOOST_ASIO_MOVE_ARG(F
) f
)
72 typename
boost::asio::decay
<F
>::type
tmp(BOOST_ASIO_MOVE_CAST(F
)(f
));
77 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
84 struct execute_free
<free_execute_const_executor
, F
>
86 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= true);
87 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
88 typedef void result_type
;
95 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
97 #if defined(BOOST_ASIO_HAS_MOVE)
99 // Support for rvalue references is required in order to use the execute
100 // customisation point with non-const member functions and free functions
101 // taking non-const arguments.
103 struct non_const_member_execute
105 template <typename F
>
106 void execute(BOOST_ASIO_MOVE_ARG(F
) f
)
108 typename
boost::asio::decay
<F
>::type
tmp(BOOST_ASIO_MOVE_CAST(F
)(f
));
113 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
119 template <typename F
>
120 struct execute_member
<non_const_member_execute
, F
>
122 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= true);
123 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
124 typedef void result_type
;
127 template <typename F
>
128 struct execute_member
<const non_const_member_execute
, F
>
130 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= false);
131 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
132 typedef void result_type
;
135 template <typename F
>
136 struct execute_member
<const non_const_member_execute
&, F
>
138 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= false);
139 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
140 typedef void result_type
;
143 } // namespace traits
147 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
149 struct free_execute_non_const_executor
151 template <typename F
>
152 friend void execute(free_execute_non_const_executor
&,
153 BOOST_ASIO_MOVE_ARG(F
) f
)
155 typename
boost::asio::decay
<F
>::type
tmp(BOOST_ASIO_MOVE_CAST(F
)(f
));
160 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
166 template <typename F
>
167 struct execute_free
<free_execute_non_const_executor
, F
>
169 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= true);
170 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
171 typedef void result_type
;
174 template <typename F
>
175 struct execute_free
<const free_execute_non_const_executor
, F
>
177 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= false);
178 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
179 typedef void result_type
;
182 template <typename F
>
183 struct execute_free
<const free_execute_non_const_executor
&, F
>
185 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= false);
186 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
187 typedef void result_type
;
190 } // namespace traits
194 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
196 #endif // defined(BOOST_ASIO_HAS_MOVE)
198 struct operation_state
200 void start() BOOST_ASIO_NOEXCEPT
209 #if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
212 struct start_member
<operation_state
>
214 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= true);
215 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= true);
216 typedef void result_type
;
219 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
221 } // namespace traits
225 struct sender
: exec::sender_base
231 template <typename R
>
232 operation_state
connect(BOOST_ASIO_MOVE_ARG(R
) r
) const
235 return operation_state();
238 template <typename R
>
239 void submit(BOOST_ASIO_MOVE_ARG(R
) r
) const
241 exec::set_value(BOOST_ASIO_MOVE_CAST(R
)(r
));
249 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
251 template <typename R
>
252 struct connect_member
<const sender
, R
>
254 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= true);
255 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
256 typedef operation_state result_type
;
259 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
261 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
263 template <typename R
>
264 struct submit_member
<const sender
, R
>
266 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid
= true);
267 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept
= false);
268 typedef void result_type
;
271 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
273 } // namespace traits
277 void test_can_execute()
279 BOOST_ASIO_CONSTEXPR
bool b1
= exec::can_execute
<
280 no_execute
&, exec::invocable_archetype
>::value
;
281 BOOST_ASIO_CHECK(b1
== false);
283 BOOST_ASIO_CONSTEXPR
bool b2
= exec::can_execute
<
284 const no_execute
&, exec::invocable_archetype
>::value
;
285 BOOST_ASIO_CHECK(b2
== false);
287 BOOST_ASIO_CONSTEXPR
bool b3
= exec::can_execute
<
288 const_member_execute
&, exec::invocable_archetype
>::value
;
289 BOOST_ASIO_CHECK(b3
== true);
291 BOOST_ASIO_CONSTEXPR
bool b4
= exec::can_execute
<
292 const const_member_execute
&, exec::invocable_archetype
>::value
;
293 BOOST_ASIO_CHECK(b4
== true);
295 BOOST_ASIO_CONSTEXPR
bool b5
= exec::can_execute
<
296 free_execute_const_executor
&, exec::invocable_archetype
>::value
;
297 BOOST_ASIO_CHECK(b5
== true);
299 BOOST_ASIO_CONSTEXPR
bool b6
= exec::can_execute
<
300 const free_execute_const_executor
&, exec::invocable_archetype
>::value
;
301 BOOST_ASIO_CHECK(b6
== true);
303 #if defined(BOOST_ASIO_HAS_MOVE)
304 BOOST_ASIO_CONSTEXPR
bool b7
= exec::can_execute
<
305 non_const_member_execute
&, exec::invocable_archetype
>::value
;
306 BOOST_ASIO_CHECK(b7
== true);
308 BOOST_ASIO_CONSTEXPR
bool b8
= exec::can_execute
<
309 const non_const_member_execute
&, exec::invocable_archetype
>::value
;
310 BOOST_ASIO_CHECK(b8
== false);
312 BOOST_ASIO_CONSTEXPR
bool b9
= exec::can_execute
<
313 free_execute_non_const_executor
&, exec::invocable_archetype
>::value
;
314 BOOST_ASIO_CHECK(b9
== true);
316 BOOST_ASIO_CONSTEXPR
bool b10
= exec::can_execute
<
317 const free_execute_non_const_executor
&, exec::invocable_archetype
>::value
;
318 BOOST_ASIO_CHECK(b10
== false);
319 #endif // defined(BOOST_ASIO_HAS_MOVE)
321 BOOST_ASIO_CONSTEXPR
bool b11
= exec::can_execute
<
322 sender
&, exec::invocable_archetype
>::value
;
323 BOOST_ASIO_CHECK(b11
== true);
325 BOOST_ASIO_CONSTEXPR
bool b12
= exec::can_execute
<
326 const sender
&, exec::invocable_archetype
>::value
;
327 BOOST_ASIO_CHECK(b12
== true);
330 void increment(int* count
)
337 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
338 namespace bindns
= boost
;
339 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
340 namespace bindns
= std
;
341 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
344 const_member_execute ex1
= {};
345 exec::execute(ex1
, bindns::bind(&increment
, &count
));
346 BOOST_ASIO_CHECK(count
== 1);
349 const const_member_execute ex2
= {};
350 exec::execute(ex2
, bindns::bind(&increment
, &count
));
351 BOOST_ASIO_CHECK(count
== 1);
354 exec::execute(const_member_execute(), bindns::bind(&increment
, &count
));
355 BOOST_ASIO_CHECK(count
== 1);
358 free_execute_const_executor ex3
= {};
359 exec::execute(ex3
, bindns::bind(&increment
, &count
));
360 BOOST_ASIO_CHECK(count
== 1);
363 const free_execute_const_executor ex4
= {};
364 exec::execute(ex4
, bindns::bind(&increment
, &count
));
365 BOOST_ASIO_CHECK(count
== 1);
368 exec::execute(free_execute_const_executor(),
369 bindns::bind(&increment
, &count
));
370 BOOST_ASIO_CHECK(count
== 1);
372 #if defined(BOOST_ASIO_HAS_MOVE)
374 non_const_member_execute ex5
= {};
375 exec::execute(ex5
, bindns::bind(&increment
, &count
));
376 BOOST_ASIO_CHECK(count
== 1);
379 free_execute_non_const_executor ex6
= {};
380 exec::execute(ex6
, bindns::bind(&increment
, &count
));
381 BOOST_ASIO_CHECK(count
== 1);
382 #endif // defined(BOOST_ASIO_HAS_MOVE)
386 exec::execute(ex3
, bindns::bind(&increment
, &count
));
387 BOOST_ASIO_CHECK(count
== 1);
391 exec::execute(ex4
, bindns::bind(&increment
, &count
));
392 BOOST_ASIO_CHECK(count
== 1);
395 BOOST_ASIO_TEST_SUITE
398 BOOST_ASIO_TEST_CASE(test_can_execute
)
399 BOOST_ASIO_TEST_CASE(test_execute
)