]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/test/execution/execute.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / asio / test / execution / execute.cpp
1 //
2 // execute.cpp
3 // ~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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 // 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)
15
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>
20
21 #include <boost/asio/execution/invocable_archetype.hpp>
22 #include "../unit_test.hpp"
23
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)
29
30 namespace exec = boost::asio::execution;
31
32 struct no_execute
33 {
34 };
35
36 struct const_member_execute
37 {
38 template <typename F>
39 void execute(BOOST_ASIO_MOVE_ARG(F) f) const
40 {
41 typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
42 tmp();
43 }
44 };
45
46 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
47
48 namespace boost {
49 namespace asio {
50 namespace traits {
51
52 template <typename F>
53 struct execute_member<const_member_execute, F>
54 {
55 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
56 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
57 typedef void result_type;
58 };
59
60 } // namespace traits
61 } // namespace asio
62 } // namespace boost
63
64 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
65
66 struct free_execute_const_executor
67 {
68 template <typename F>
69 friend void execute(const free_execute_const_executor&,
70 BOOST_ASIO_MOVE_ARG(F) f)
71 {
72 typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
73 tmp();
74 }
75 };
76
77 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
78
79 namespace boost {
80 namespace asio {
81 namespace traits {
82
83 template <typename F>
84 struct execute_free<free_execute_const_executor, F>
85 {
86 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
87 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
88 typedef void result_type;
89 };
90
91 } // namespace traits
92 } // namespace asio
93 } // namespace boost
94
95 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
96
97 #if defined(BOOST_ASIO_HAS_MOVE)
98
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.
102
103 struct non_const_member_execute
104 {
105 template <typename F>
106 void execute(BOOST_ASIO_MOVE_ARG(F) f)
107 {
108 typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
109 tmp();
110 }
111 };
112
113 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
114
115 namespace boost {
116 namespace asio {
117 namespace traits {
118
119 template <typename F>
120 struct execute_member<non_const_member_execute, F>
121 {
122 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
123 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
124 typedef void result_type;
125 };
126
127 template <typename F>
128 struct execute_member<const non_const_member_execute, F>
129 {
130 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
131 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
132 typedef void result_type;
133 };
134
135 template <typename F>
136 struct execute_member<const non_const_member_execute&, F>
137 {
138 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
139 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
140 typedef void result_type;
141 };
142
143 } // namespace traits
144 } // namespace asio
145 } // namespace boost
146
147 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
148
149 struct free_execute_non_const_executor
150 {
151 template <typename F>
152 friend void execute(free_execute_non_const_executor&,
153 BOOST_ASIO_MOVE_ARG(F) f)
154 {
155 typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
156 tmp();
157 }
158 };
159
160 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
161
162 namespace boost {
163 namespace asio {
164 namespace traits {
165
166 template <typename F>
167 struct execute_free<free_execute_non_const_executor, F>
168 {
169 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
170 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
171 typedef void result_type;
172 };
173
174 template <typename F>
175 struct execute_free<const free_execute_non_const_executor, F>
176 {
177 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
178 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
179 typedef void result_type;
180 };
181
182 template <typename F>
183 struct execute_free<const free_execute_non_const_executor&, F>
184 {
185 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
186 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
187 typedef void result_type;
188 };
189
190 } // namespace traits
191 } // namespace asio
192 } // namespace boost
193
194 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
195
196 #endif // defined(BOOST_ASIO_HAS_MOVE)
197
198 struct operation_state
199 {
200 void start() BOOST_ASIO_NOEXCEPT
201 {
202 }
203 };
204
205 namespace boost {
206 namespace asio {
207 namespace traits {
208
209 #if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
210
211 template <>
212 struct start_member<operation_state>
213 {
214 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
215 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
216 typedef void result_type;
217 };
218
219 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
220
221 } // namespace traits
222 } // namespace asio
223 } // namespace boost
224
225 struct sender : exec::sender_base
226 {
227 sender()
228 {
229 }
230
231 template <typename R>
232 operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
233 {
234 (void)r;
235 return operation_state();
236 }
237
238 template <typename R>
239 void submit(BOOST_ASIO_MOVE_ARG(R) r) const
240 {
241 exec::set_value(BOOST_ASIO_MOVE_CAST(R)(r));
242 }
243 };
244
245 namespace boost {
246 namespace asio {
247 namespace traits {
248
249 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
250
251 template <typename R>
252 struct connect_member<const sender, R>
253 {
254 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
255 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
256 typedef operation_state result_type;
257 };
258
259 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
260
261 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
262
263 template <typename R>
264 struct submit_member<const sender, R>
265 {
266 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
267 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
268 typedef void result_type;
269 };
270
271 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
272
273 } // namespace traits
274 } // namespace asio
275 } // namespace boost
276
277 void test_can_execute()
278 {
279 BOOST_ASIO_CONSTEXPR bool b1 = exec::can_execute<
280 no_execute&, exec::invocable_archetype>::value;
281 BOOST_ASIO_CHECK(b1 == false);
282
283 BOOST_ASIO_CONSTEXPR bool b2 = exec::can_execute<
284 const no_execute&, exec::invocable_archetype>::value;
285 BOOST_ASIO_CHECK(b2 == false);
286
287 BOOST_ASIO_CONSTEXPR bool b3 = exec::can_execute<
288 const_member_execute&, exec::invocable_archetype>::value;
289 BOOST_ASIO_CHECK(b3 == true);
290
291 BOOST_ASIO_CONSTEXPR bool b4 = exec::can_execute<
292 const const_member_execute&, exec::invocable_archetype>::value;
293 BOOST_ASIO_CHECK(b4 == true);
294
295 BOOST_ASIO_CONSTEXPR bool b5 = exec::can_execute<
296 free_execute_const_executor&, exec::invocable_archetype>::value;
297 BOOST_ASIO_CHECK(b5 == true);
298
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);
302
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);
307
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);
311
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);
315
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)
320
321 BOOST_ASIO_CONSTEXPR bool b11 = exec::can_execute<
322 sender&, exec::invocable_archetype>::value;
323 BOOST_ASIO_CHECK(b11 == true);
324
325 BOOST_ASIO_CONSTEXPR bool b12 = exec::can_execute<
326 const sender&, exec::invocable_archetype>::value;
327 BOOST_ASIO_CHECK(b12 == true);
328 }
329
330 void increment(int* count)
331 {
332 ++(*count);
333 }
334
335 void test_execute()
336 {
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)
342
343 int count = 0;
344 const_member_execute ex1 = {};
345 exec::execute(ex1, bindns::bind(&increment, &count));
346 BOOST_ASIO_CHECK(count == 1);
347
348 count = 0;
349 const const_member_execute ex2 = {};
350 exec::execute(ex2, bindns::bind(&increment, &count));
351 BOOST_ASIO_CHECK(count == 1);
352
353 count = 0;
354 exec::execute(const_member_execute(), bindns::bind(&increment, &count));
355 BOOST_ASIO_CHECK(count == 1);
356
357 count = 0;
358 free_execute_const_executor ex3 = {};
359 exec::execute(ex3, bindns::bind(&increment, &count));
360 BOOST_ASIO_CHECK(count == 1);
361
362 count = 0;
363 const free_execute_const_executor ex4 = {};
364 exec::execute(ex4, bindns::bind(&increment, &count));
365 BOOST_ASIO_CHECK(count == 1);
366
367 count = 0;
368 exec::execute(free_execute_const_executor(),
369 bindns::bind(&increment, &count));
370 BOOST_ASIO_CHECK(count == 1);
371
372 #if defined(BOOST_ASIO_HAS_MOVE)
373 count = 0;
374 non_const_member_execute ex5 = {};
375 exec::execute(ex5, bindns::bind(&increment, &count));
376 BOOST_ASIO_CHECK(count == 1);
377
378 count = 0;
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)
383
384 count = 0;
385 sender ex7;
386 exec::execute(ex3, bindns::bind(&increment, &count));
387 BOOST_ASIO_CHECK(count == 1);
388
389 count = 0;
390 const sender ex8;
391 exec::execute(ex4, bindns::bind(&increment, &count));
392 BOOST_ASIO_CHECK(count == 1);
393 }
394
395 BOOST_ASIO_TEST_SUITE
396 (
397 "blocking",
398 BOOST_ASIO_TEST_CASE(test_can_execute)
399 BOOST_ASIO_TEST_CASE(test_execute)
400 )