]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // |
2 | // prefer_only.cpp | |
3 | // ~~~~~~~~~~~~~~~ | |
4 | // | |
1e59de90 | 5 | // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
20effc67 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 | // 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/prefer_only.hpp> | |
18 | ||
19 | #include <boost/asio/execution/any_executor.hpp> | |
20 | #include "../unit_test.hpp" | |
21 | ||
22 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) | |
23 | # include <boost/bind/bind.hpp> | |
24 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) | |
25 | # include <functional> | |
26 | #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) | |
27 | ||
28 | using namespace boost::asio; | |
29 | ||
30 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) | |
31 | namespace bindns = boost; | |
32 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) | |
33 | namespace bindns = std; | |
34 | #endif | |
35 | ||
36 | static int possibly_blocking_count = 0; | |
37 | static int never_blocking_count = 0; | |
38 | ||
39 | struct possibly_blocking_executor | |
40 | { | |
41 | template <typename F> | |
42 | void execute(const F&) const | |
43 | { | |
44 | ++possibly_blocking_count; | |
45 | } | |
46 | ||
47 | friend bool operator==(const possibly_blocking_executor&, | |
48 | const possibly_blocking_executor&) BOOST_ASIO_NOEXCEPT | |
49 | { | |
50 | return true; | |
51 | } | |
52 | ||
53 | friend bool operator!=(const possibly_blocking_executor&, | |
54 | const possibly_blocking_executor&) BOOST_ASIO_NOEXCEPT | |
55 | { | |
56 | return false; | |
57 | } | |
58 | }; | |
59 | ||
60 | namespace boost { | |
61 | namespace asio { | |
62 | namespace traits { | |
63 | ||
64 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) | |
65 | ||
66 | template <typename F> | |
67 | struct execute_member<possibly_blocking_executor, F> | |
68 | { | |
69 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
70 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
71 | typedef void result_type; | |
72 | }; | |
73 | ||
74 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) | |
75 | ||
76 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) | |
77 | ||
78 | template <> | |
79 | struct equality_comparable<possibly_blocking_executor> | |
80 | { | |
81 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
82 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
83 | }; | |
84 | ||
85 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) | |
86 | ||
87 | } // namespace traits | |
88 | } // namespace asio | |
89 | } // namespace boost | |
90 | ||
91 | struct never_blocking_executor | |
92 | { | |
93 | static BOOST_ASIO_CONSTEXPR execution::blocking_t::never_t | |
94 | query(execution::blocking_t) BOOST_ASIO_NOEXCEPT | |
95 | { | |
96 | return execution::blocking_t::never_t(); | |
97 | } | |
98 | ||
99 | template <typename F> | |
100 | void execute(const F&) const | |
101 | { | |
102 | ++never_blocking_count; | |
103 | } | |
104 | ||
105 | friend bool operator==(const never_blocking_executor&, | |
106 | const never_blocking_executor&) BOOST_ASIO_NOEXCEPT | |
107 | { | |
108 | return true; | |
109 | } | |
110 | ||
111 | friend bool operator!=(const never_blocking_executor&, | |
112 | const never_blocking_executor&) BOOST_ASIO_NOEXCEPT | |
113 | { | |
114 | return false; | |
115 | } | |
116 | }; | |
117 | ||
118 | namespace boost { | |
119 | namespace asio { | |
120 | namespace traits { | |
121 | ||
122 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) | |
123 | ||
124 | template <typename F> | |
125 | struct execute_member<never_blocking_executor, F> | |
126 | { | |
127 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
128 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
129 | typedef void result_type; | |
130 | }; | |
131 | ||
132 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) | |
133 | ||
134 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) | |
135 | ||
136 | template <> | |
137 | struct equality_comparable<never_blocking_executor> | |
138 | { | |
139 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
140 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
141 | }; | |
142 | ||
143 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) | |
144 | ||
145 | #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) | |
146 | ||
147 | template <typename Param> | |
148 | struct query_static_constexpr_member< | |
149 | never_blocking_executor, Param, | |
150 | typename boost::asio::enable_if< | |
151 | boost::asio::is_convertible<Param, execution::blocking_t>::value | |
152 | >::type> | |
153 | { | |
154 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
155 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
156 | ||
157 | typedef execution::blocking_t::never_t result_type; | |
158 | ||
159 | static BOOST_ASIO_CONSTEXPR result_type value() | |
160 | { | |
161 | return result_type(); | |
162 | } | |
163 | }; | |
164 | ||
165 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) | |
166 | ||
167 | } // namespace traits | |
168 | } // namespace asio | |
169 | } // namespace boost | |
170 | ||
171 | struct either_blocking_executor | |
172 | { | |
173 | execution::blocking_t blocking_; | |
174 | ||
175 | explicit either_blocking_executor(execution::blocking_t b) | |
176 | : blocking_(b) | |
177 | { | |
178 | } | |
179 | ||
180 | execution::blocking_t query(execution::blocking_t) const BOOST_ASIO_NOEXCEPT | |
181 | { | |
182 | return blocking_; | |
183 | } | |
184 | ||
185 | either_blocking_executor require(execution::blocking_t::possibly_t) const | |
186 | { | |
187 | return either_blocking_executor(execution::blocking.possibly); | |
188 | } | |
189 | ||
190 | either_blocking_executor require(execution::blocking_t::never_t) const | |
191 | { | |
192 | return either_blocking_executor(execution::blocking.never); | |
193 | } | |
194 | ||
195 | template <typename F> | |
196 | void execute(const F&) const | |
197 | { | |
198 | if (blocking_ == execution::blocking.never) | |
199 | ++never_blocking_count; | |
200 | else | |
201 | ++possibly_blocking_count; | |
202 | } | |
203 | ||
204 | friend bool operator==(const either_blocking_executor& a, | |
205 | const either_blocking_executor& b) BOOST_ASIO_NOEXCEPT | |
206 | { | |
207 | return a.blocking_ == b.blocking_; | |
208 | } | |
209 | ||
210 | friend bool operator!=(const either_blocking_executor& a, | |
211 | const either_blocking_executor& b) BOOST_ASIO_NOEXCEPT | |
212 | { | |
213 | return a.blocking_ != b.blocking_; | |
214 | } | |
215 | }; | |
216 | ||
217 | namespace boost { | |
218 | namespace asio { | |
219 | namespace traits { | |
220 | ||
221 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) | |
222 | ||
223 | template <typename F> | |
224 | struct execute_member<either_blocking_executor, F> | |
225 | { | |
226 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
227 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
228 | typedef void result_type; | |
229 | }; | |
230 | ||
231 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) | |
232 | ||
233 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) | |
234 | ||
235 | template <> | |
236 | struct equality_comparable<either_blocking_executor> | |
237 | { | |
238 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
239 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
240 | }; | |
241 | ||
242 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) | |
243 | ||
244 | #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) | |
245 | ||
246 | template <typename Param> | |
247 | struct query_member< | |
248 | either_blocking_executor, Param, | |
249 | typename boost::asio::enable_if< | |
250 | boost::asio::is_convertible<Param, execution::blocking_t>::value | |
251 | >::type> | |
252 | { | |
253 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
254 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); | |
255 | ||
256 | typedef execution::blocking_t result_type; | |
257 | }; | |
258 | ||
259 | #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) | |
260 | ||
261 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) | |
262 | ||
263 | template <typename Param> | |
264 | struct require_member< | |
265 | either_blocking_executor, Param, | |
266 | typename boost::asio::enable_if< | |
267 | boost::asio::is_convertible<Param, execution::blocking_t>::value | |
268 | >::type> | |
269 | { | |
270 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); | |
271 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); | |
272 | ||
273 | typedef either_blocking_executor result_type; | |
274 | }; | |
275 | ||
276 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) | |
277 | ||
278 | } // namespace traits | |
279 | } // namespace asio | |
280 | } // namespace boost | |
281 | ||
282 | void prefer_only_executor_query_test() | |
283 | { | |
284 | typedef execution::any_executor< | |
285 | execution::blocking_t, | |
286 | execution::prefer_only<execution::blocking_t::possibly_t>, | |
287 | execution::prefer_only<execution::blocking_t::never_t> | |
288 | > executor_type; | |
289 | ||
290 | executor_type ex1 = possibly_blocking_executor(); | |
291 | ||
292 | BOOST_ASIO_CHECK( | |
293 | boost::asio::query(ex1, execution::blocking) | |
294 | == execution::blocking.possibly); | |
295 | ||
296 | BOOST_ASIO_CHECK( | |
297 | boost::asio::query(ex1, execution::blocking.possibly) | |
298 | == execution::blocking.possibly); | |
299 | ||
300 | BOOST_ASIO_CHECK( | |
301 | boost::asio::query(ex1, execution::blocking.never) | |
302 | == execution::blocking.possibly); | |
303 | ||
304 | executor_type ex2 = boost::asio::prefer(ex1, execution::blocking.possibly); | |
305 | ||
306 | BOOST_ASIO_CHECK( | |
307 | boost::asio::query(ex2, execution::blocking) | |
308 | == execution::blocking.possibly); | |
309 | ||
310 | BOOST_ASIO_CHECK( | |
311 | boost::asio::query(ex2, execution::blocking.possibly) | |
312 | == execution::blocking.possibly); | |
313 | ||
314 | BOOST_ASIO_CHECK( | |
315 | boost::asio::query(ex2, execution::blocking.never) | |
316 | == execution::blocking.possibly); | |
317 | ||
318 | executor_type ex3 = boost::asio::prefer(ex1, execution::blocking.never); | |
319 | ||
320 | BOOST_ASIO_CHECK( | |
321 | boost::asio::query(ex3, execution::blocking) | |
322 | == execution::blocking.possibly); | |
323 | ||
324 | BOOST_ASIO_CHECK( | |
325 | boost::asio::query(ex3, execution::blocking.possibly) | |
326 | == execution::blocking.possibly); | |
327 | ||
328 | BOOST_ASIO_CHECK( | |
329 | boost::asio::query(ex3, execution::blocking.never) | |
330 | == execution::blocking.possibly); | |
331 | ||
332 | executor_type ex4 = never_blocking_executor(); | |
333 | ||
334 | BOOST_ASIO_CHECK( | |
335 | boost::asio::query(ex4, execution::blocking) | |
336 | == execution::blocking.never); | |
337 | ||
338 | BOOST_ASIO_CHECK( | |
339 | boost::asio::query(ex4, execution::blocking.possibly) | |
340 | == execution::blocking.never); | |
341 | ||
342 | BOOST_ASIO_CHECK( | |
343 | boost::asio::query(ex4, execution::blocking.never) | |
344 | == execution::blocking.never); | |
345 | ||
346 | executor_type ex5 = boost::asio::prefer(ex4, execution::blocking.possibly); | |
347 | ||
348 | BOOST_ASIO_CHECK( | |
349 | boost::asio::query(ex5, execution::blocking) | |
350 | == execution::blocking.never); | |
351 | ||
352 | BOOST_ASIO_CHECK( | |
353 | boost::asio::query(ex5, execution::blocking.possibly) | |
354 | == execution::blocking.never); | |
355 | ||
356 | BOOST_ASIO_CHECK( | |
357 | boost::asio::query(ex5, execution::blocking.never) | |
358 | == execution::blocking.never); | |
359 | ||
360 | executor_type ex6 = boost::asio::prefer(ex4, execution::blocking.never); | |
361 | ||
362 | BOOST_ASIO_CHECK( | |
363 | boost::asio::query(ex6, execution::blocking) | |
364 | == execution::blocking.never); | |
365 | ||
366 | BOOST_ASIO_CHECK( | |
367 | boost::asio::query(ex6, execution::blocking.possibly) | |
368 | == execution::blocking.never); | |
369 | ||
370 | BOOST_ASIO_CHECK( | |
371 | boost::asio::query(ex6, execution::blocking.never) | |
372 | == execution::blocking.never); | |
373 | ||
374 | executor_type ex7 = either_blocking_executor(execution::blocking.possibly); | |
375 | ||
376 | BOOST_ASIO_CHECK( | |
377 | boost::asio::query(ex7, execution::blocking) | |
378 | == execution::blocking.possibly); | |
379 | ||
380 | BOOST_ASIO_CHECK( | |
381 | boost::asio::query(ex7, execution::blocking.possibly) | |
382 | == execution::blocking.possibly); | |
383 | ||
384 | BOOST_ASIO_CHECK( | |
385 | boost::asio::query(ex7, execution::blocking.never) | |
386 | == execution::blocking.possibly); | |
387 | ||
388 | executor_type ex8 = boost::asio::prefer(ex7, execution::blocking.possibly); | |
389 | ||
390 | BOOST_ASIO_CHECK( | |
391 | boost::asio::query(ex8, execution::blocking) | |
392 | == execution::blocking.possibly); | |
393 | ||
394 | BOOST_ASIO_CHECK( | |
395 | boost::asio::query(ex8, execution::blocking.possibly) | |
396 | == execution::blocking.possibly); | |
397 | ||
398 | BOOST_ASIO_CHECK( | |
399 | boost::asio::query(ex8, execution::blocking.never) | |
400 | == execution::blocking.possibly); | |
401 | ||
402 | executor_type ex9 = boost::asio::prefer(ex7, execution::blocking.never); | |
403 | ||
404 | BOOST_ASIO_CHECK( | |
405 | boost::asio::query(ex9, execution::blocking) | |
406 | == execution::blocking.never); | |
407 | ||
408 | BOOST_ASIO_CHECK( | |
409 | boost::asio::query(ex9, execution::blocking.possibly) | |
410 | == execution::blocking.never); | |
411 | ||
412 | BOOST_ASIO_CHECK( | |
413 | boost::asio::query(ex9, execution::blocking.never) | |
414 | == execution::blocking.never); | |
415 | ||
416 | executor_type ex10 = either_blocking_executor(execution::blocking.never); | |
417 | ||
418 | BOOST_ASIO_CHECK( | |
419 | boost::asio::query(ex10, execution::blocking) | |
420 | == execution::blocking.never); | |
421 | ||
422 | BOOST_ASIO_CHECK( | |
423 | boost::asio::query(ex10, execution::blocking.possibly) | |
424 | == execution::blocking.never); | |
425 | ||
426 | BOOST_ASIO_CHECK( | |
427 | boost::asio::query(ex10, execution::blocking.never) | |
428 | == execution::blocking.never); | |
429 | ||
430 | executor_type ex11 = boost::asio::prefer(ex7, execution::blocking.possibly); | |
431 | ||
432 | BOOST_ASIO_CHECK( | |
433 | boost::asio::query(ex11, execution::blocking) | |
434 | == execution::blocking.possibly); | |
435 | ||
436 | BOOST_ASIO_CHECK( | |
437 | boost::asio::query(ex11, execution::blocking.possibly) | |
438 | == execution::blocking.possibly); | |
439 | ||
440 | BOOST_ASIO_CHECK( | |
441 | boost::asio::query(ex11, execution::blocking.never) | |
442 | == execution::blocking.possibly); | |
443 | ||
444 | executor_type ex12 = boost::asio::prefer(ex7, execution::blocking.never); | |
445 | ||
446 | BOOST_ASIO_CHECK( | |
447 | boost::asio::query(ex12, execution::blocking) | |
448 | == execution::blocking.never); | |
449 | ||
450 | BOOST_ASIO_CHECK( | |
451 | boost::asio::query(ex12, execution::blocking.possibly) | |
452 | == execution::blocking.never); | |
453 | ||
454 | BOOST_ASIO_CHECK( | |
455 | boost::asio::query(ex12, execution::blocking.never) | |
456 | == execution::blocking.never); | |
457 | } | |
458 | ||
459 | void do_nothing() | |
460 | { | |
461 | } | |
462 | ||
463 | void prefer_only_executor_execute_test() | |
464 | { | |
465 | typedef execution::any_executor< | |
466 | execution::blocking_t, | |
467 | execution::prefer_only<execution::blocking_t::possibly_t>, | |
468 | execution::prefer_only<execution::blocking_t::never_t> | |
469 | > executor_type; | |
470 | ||
471 | executor_type ex1 = possibly_blocking_executor(); | |
472 | ||
473 | execution::execute(ex1, &do_nothing); | |
474 | BOOST_ASIO_CHECK(possibly_blocking_count == 1); | |
475 | BOOST_ASIO_CHECK(never_blocking_count == 0); | |
476 | ||
477 | executor_type ex2 = boost::asio::prefer(ex1, execution::blocking.possibly); | |
478 | ||
479 | execution::execute(ex2, &do_nothing); | |
480 | BOOST_ASIO_CHECK(possibly_blocking_count == 2); | |
481 | BOOST_ASIO_CHECK(never_blocking_count == 0); | |
482 | ||
483 | executor_type ex3 = boost::asio::prefer(ex1, execution::blocking.never); | |
484 | ||
485 | execution::execute(ex3, &do_nothing); | |
486 | BOOST_ASIO_CHECK(possibly_blocking_count == 3); | |
487 | BOOST_ASIO_CHECK(never_blocking_count == 0); | |
488 | ||
489 | executor_type ex4 = never_blocking_executor(); | |
490 | ||
491 | execution::execute(ex4, &do_nothing); | |
492 | BOOST_ASIO_CHECK(possibly_blocking_count == 3); | |
493 | BOOST_ASIO_CHECK(never_blocking_count == 1); | |
494 | ||
495 | executor_type ex5 = boost::asio::prefer(ex4, execution::blocking.possibly); | |
496 | ||
497 | execution::execute(ex5, &do_nothing); | |
498 | BOOST_ASIO_CHECK(possibly_blocking_count == 3); | |
499 | BOOST_ASIO_CHECK(never_blocking_count == 2); | |
500 | ||
501 | executor_type ex6 = boost::asio::prefer(ex4, execution::blocking.never); | |
502 | ||
503 | execution::execute(ex6, &do_nothing); | |
504 | BOOST_ASIO_CHECK(possibly_blocking_count == 3); | |
505 | BOOST_ASIO_CHECK(never_blocking_count == 3); | |
506 | ||
507 | executor_type ex7 = either_blocking_executor(execution::blocking.possibly); | |
508 | ||
509 | execution::execute(ex7, &do_nothing); | |
510 | BOOST_ASIO_CHECK(possibly_blocking_count == 4); | |
511 | BOOST_ASIO_CHECK(never_blocking_count == 3); | |
512 | ||
513 | executor_type ex8 = boost::asio::prefer(ex7, execution::blocking.possibly); | |
514 | ||
515 | execution::execute(ex8, &do_nothing); | |
516 | BOOST_ASIO_CHECK(possibly_blocking_count == 5); | |
517 | BOOST_ASIO_CHECK(never_blocking_count == 3); | |
518 | ||
519 | executor_type ex9 = boost::asio::prefer(ex7, execution::blocking.never); | |
520 | ||
521 | execution::execute(ex9, &do_nothing); | |
522 | BOOST_ASIO_CHECK(possibly_blocking_count == 5); | |
523 | BOOST_ASIO_CHECK(never_blocking_count == 4); | |
524 | ||
525 | executor_type ex10 = either_blocking_executor(execution::blocking.never); | |
526 | ||
527 | execution::execute(ex10, &do_nothing); | |
528 | BOOST_ASIO_CHECK(possibly_blocking_count == 5); | |
529 | BOOST_ASIO_CHECK(never_blocking_count == 5); | |
530 | ||
531 | executor_type ex11 = boost::asio::prefer(ex7, execution::blocking.possibly); | |
532 | ||
533 | execution::execute(ex11, &do_nothing); | |
534 | BOOST_ASIO_CHECK(possibly_blocking_count == 6); | |
535 | BOOST_ASIO_CHECK(never_blocking_count == 5); | |
536 | ||
537 | executor_type ex12 = boost::asio::prefer(ex7, execution::blocking.never); | |
538 | ||
539 | execution::execute(ex12, &do_nothing); | |
540 | BOOST_ASIO_CHECK(possibly_blocking_count == 6); | |
541 | BOOST_ASIO_CHECK(never_blocking_count == 6); | |
542 | } | |
543 | ||
544 | BOOST_ASIO_TEST_SUITE | |
545 | ( | |
546 | "prefer_only", | |
547 | BOOST_ASIO_TEST_CASE(prefer_only_executor_query_test) | |
548 | BOOST_ASIO_TEST_CASE(prefer_only_executor_execute_test) | |
549 | ) |