• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // any_executor.cpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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/any_executor.hpp>
18 
19 #include <cstring>
20 #include <boost/asio/thread_pool.hpp>
21 #include "../unit_test.hpp"
22 
23 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
24 # include <boost/bind/bind.hpp>
25 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
26 # include <functional>
27 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
28 
29 using namespace boost::asio;
30 
31 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
32 namespace bindns = boost;
33 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
34 namespace bindns = std;
35 #endif
36 
37 struct fat_executor
38 {
fat_executorfat_executor39   fat_executor(int id)
40     : id_(id)
41   {
42     std::memset(data_, 0, sizeof(data_));
43   }
44 
45   template <typename F>
executefat_executor46   void execute(const F&) const
47   {
48   }
49 
queryfat_executor50   std::size_t query(execution::occupancy_t) const
51   {
52     return 1;
53   }
54 
operator ==(const fat_executor & a,const fat_executor & b)55   friend bool operator==(const fat_executor& a,
56       const fat_executor& b) BOOST_ASIO_NOEXCEPT
57   {
58     return a.id_ == b.id_;
59   }
60 
operator !=(const fat_executor & a,const fat_executor & b)61   friend bool operator!=(const fat_executor& a,
62       const fat_executor& b) BOOST_ASIO_NOEXCEPT
63   {
64     return a.id_ != b.id_;
65   }
66 
67   int id_;
68   unsigned char data_[1024];
69 };
70 
71 namespace boost {
72 namespace asio {
73 namespace traits {
74 
75 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
76 
77 template <typename F>
78 struct execute_member<fat_executor, F>
79 {
80   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
81   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
82   typedef void result_type;
83 };
84 
85 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
86 
87 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
88 
89 template <>
90 struct query_member<fat_executor, execution::occupancy_t>
91 {
92   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
93   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
94   typedef std::size_t result_type;
95 };
96 
97 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
98 
99 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
100 
101 template <>
102 struct equality_comparable<fat_executor>
103 {
104   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
105   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
106 };
107 
108 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
109 
110 } // namespace traits
111 } // namespace asio
112 } // namespace boost
113 
increment(int * count)114 void increment(int* count)
115 {
116   ++(*count);
117 }
118 
any_executor_construction_test()119 void any_executor_construction_test()
120 {
121   typedef execution::any_executor<> ex_no_props_t;
122 
123   typedef execution::any_executor<
124       execution::blocking_t
125     > ex_one_prop_t;
126 
127   typedef execution::any_executor<
128       execution::blocking_t,
129       execution::occupancy_t
130     > ex_two_props_t;
131 
132   thread_pool pool(1);
133   boost::asio::nullptr_t null_ptr = boost::asio::nullptr_t();
134 
135   ex_two_props_t ex_two_props_1;
136 
137   BOOST_ASIO_CHECK(ex_two_props_1.target<void>() == 0);
138   BOOST_ASIO_CHECK(ex_two_props_1 == null_ptr);
139 
140   ex_two_props_t ex_two_props_2(null_ptr);
141 
142   BOOST_ASIO_CHECK(ex_two_props_2.target<void>() == 0);
143   BOOST_ASIO_CHECK(ex_two_props_2 == null_ptr);
144   BOOST_ASIO_CHECK(ex_two_props_2 == ex_two_props_1);
145 
146   ex_two_props_t ex_two_props_3(pool.executor());
147 
148   BOOST_ASIO_CHECK(ex_two_props_3.target<void>() != 0);
149   BOOST_ASIO_CHECK(ex_two_props_3 != null_ptr);
150   BOOST_ASIO_CHECK(ex_two_props_3 != ex_two_props_1);
151 
152   ex_two_props_t ex_two_props_4(ex_two_props_1);
153 
154   BOOST_ASIO_CHECK(ex_two_props_4.target<void>() == 0);
155   BOOST_ASIO_CHECK(ex_two_props_4 == null_ptr);
156   BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_1);
157 
158   ex_two_props_t ex_two_props_5(ex_two_props_3);
159 
160   BOOST_ASIO_CHECK(ex_two_props_5.target<void>() != 0);
161   BOOST_ASIO_CHECK(ex_two_props_5 != null_ptr);
162   BOOST_ASIO_CHECK(ex_two_props_5 == ex_two_props_3);
163 
164   ex_two_props_t ex_two_props_6 = fat_executor(1);
165 
166   BOOST_ASIO_CHECK(ex_two_props_6.target<void>() != 0);
167   BOOST_ASIO_CHECK(ex_two_props_6 != null_ptr);
168   BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_1);
169 
170   ex_two_props_t ex_two_props_7 = fat_executor(1);
171 
172   BOOST_ASIO_CHECK(ex_two_props_7.target<void>() != 0);
173   BOOST_ASIO_CHECK(ex_two_props_7 != null_ptr);
174   BOOST_ASIO_CHECK(ex_two_props_7 != ex_two_props_1);
175   BOOST_ASIO_CHECK(ex_two_props_7 == ex_two_props_6);
176 
177   ex_two_props_t ex_two_props_8 = fat_executor(2);
178 
179   BOOST_ASIO_CHECK(ex_two_props_8.target<void>() != 0);
180   BOOST_ASIO_CHECK(ex_two_props_8 != null_ptr);
181   BOOST_ASIO_CHECK(ex_two_props_8 != ex_two_props_1);
182   BOOST_ASIO_CHECK(ex_two_props_8 != ex_two_props_6);
183   BOOST_ASIO_CHECK(ex_two_props_8 != ex_two_props_7);
184 
185   ex_two_props_t ex_two_props_9(ex_two_props_6);
186 
187   BOOST_ASIO_CHECK(ex_two_props_9.target<void>() != 0);
188   BOOST_ASIO_CHECK(ex_two_props_9 != null_ptr);
189   BOOST_ASIO_CHECK(ex_two_props_9 != ex_two_props_1);
190   BOOST_ASIO_CHECK(ex_two_props_9 == ex_two_props_6);
191   BOOST_ASIO_CHECK(ex_two_props_9 == ex_two_props_7);
192   BOOST_ASIO_CHECK(ex_two_props_9 != ex_two_props_8);
193 
194 #if defined(BOOST_ASIO_HAS_MOVE)
195   ex_two_props_t ex_two_props_10(std::move(ex_two_props_1));
196 
197   BOOST_ASIO_CHECK(ex_two_props_10.target<void>() == 0);
198   BOOST_ASIO_CHECK(ex_two_props_10 == null_ptr);
199   BOOST_ASIO_CHECK(ex_two_props_1.target<void>() == 0);
200   BOOST_ASIO_CHECK(ex_two_props_1 == null_ptr);
201 
202   ex_two_props_t ex_two_props_11(std::move(ex_two_props_3));
203 
204   BOOST_ASIO_CHECK(ex_two_props_11.target<void>() != 0);
205   BOOST_ASIO_CHECK(ex_two_props_11 != null_ptr);
206   BOOST_ASIO_CHECK(ex_two_props_3.target<void>() == 0);
207   BOOST_ASIO_CHECK(ex_two_props_3 == null_ptr);
208   BOOST_ASIO_CHECK(ex_two_props_11 == ex_two_props_5);
209 
210   ex_two_props_t ex_two_props_12(std::move(ex_two_props_7));
211 
212   BOOST_ASIO_CHECK(ex_two_props_12.target<void>() != 0);
213   BOOST_ASIO_CHECK(ex_two_props_12 != null_ptr);
214   BOOST_ASIO_CHECK(ex_two_props_7.target<void>() == 0);
215   BOOST_ASIO_CHECK(ex_two_props_7 == null_ptr);
216   BOOST_ASIO_CHECK(ex_two_props_12 == ex_two_props_6);
217   BOOST_ASIO_CHECK(ex_two_props_12 != ex_two_props_8);
218 #endif // defined(BOOST_ASIO_HAS_MOVE)
219 
220   ex_one_prop_t ex_one_prop_1;
221 
222   BOOST_ASIO_CHECK(ex_one_prop_1.target<void>() == 0);
223   BOOST_ASIO_CHECK(ex_one_prop_1 == null_ptr);
224 
225   ex_one_prop_t ex_one_prop_2(null_ptr);
226 
227   BOOST_ASIO_CHECK(ex_one_prop_2.target<void>() == 0);
228   BOOST_ASIO_CHECK(ex_one_prop_2 == null_ptr);
229   BOOST_ASIO_CHECK(ex_one_prop_2 == ex_one_prop_1);
230 
231   ex_one_prop_t ex_one_prop_3(pool.executor());
232 
233   BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() != 0);
234   BOOST_ASIO_CHECK(ex_one_prop_3 != null_ptr);
235   BOOST_ASIO_CHECK(ex_one_prop_3 != ex_one_prop_1);
236 
237   ex_one_prop_t ex_one_prop_4(ex_one_prop_1);
238 
239   BOOST_ASIO_CHECK(ex_one_prop_4.target<void>() == 0);
240   BOOST_ASIO_CHECK(ex_one_prop_4 == null_ptr);
241   BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_1);
242 
243   ex_one_prop_t ex_one_prop_5(ex_one_prop_3);
244 
245   BOOST_ASIO_CHECK(ex_one_prop_5.target<void>() != 0);
246   BOOST_ASIO_CHECK(ex_one_prop_5 != null_ptr);
247   BOOST_ASIO_CHECK(ex_one_prop_5 == ex_one_prop_3);
248 
249   ex_one_prop_t ex_one_prop_6 = fat_executor(1);
250 
251   BOOST_ASIO_CHECK(ex_one_prop_6.target<void>() != 0);
252   BOOST_ASIO_CHECK(ex_one_prop_6 != null_ptr);
253   BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_1);
254 
255   ex_one_prop_t ex_one_prop_7 = fat_executor(1);
256 
257   BOOST_ASIO_CHECK(ex_one_prop_7.target<void>() != 0);
258   BOOST_ASIO_CHECK(ex_one_prop_7 != null_ptr);
259   BOOST_ASIO_CHECK(ex_one_prop_7 != ex_one_prop_1);
260   BOOST_ASIO_CHECK(ex_one_prop_7 == ex_one_prop_6);
261 
262   ex_one_prop_t ex_one_prop_8 = fat_executor(2);
263 
264   BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() != 0);
265   BOOST_ASIO_CHECK(ex_one_prop_8 != null_ptr);
266   BOOST_ASIO_CHECK(ex_one_prop_8 != ex_one_prop_1);
267   BOOST_ASIO_CHECK(ex_one_prop_8 != ex_one_prop_6);
268   BOOST_ASIO_CHECK(ex_one_prop_8 != ex_one_prop_7);
269 
270   ex_one_prop_t ex_one_prop_9(ex_one_prop_6);
271 
272   BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() != 0);
273   BOOST_ASIO_CHECK(ex_one_prop_9 != null_ptr);
274   BOOST_ASIO_CHECK(ex_one_prop_9 != ex_one_prop_1);
275   BOOST_ASIO_CHECK(ex_one_prop_9 == ex_one_prop_6);
276   BOOST_ASIO_CHECK(ex_one_prop_9 == ex_one_prop_7);
277   BOOST_ASIO_CHECK(ex_one_prop_9 != ex_one_prop_8);
278 
279 #if defined(BOOST_ASIO_HAS_MOVE)
280   ex_one_prop_t ex_one_prop_10(std::move(ex_one_prop_1));
281 
282   BOOST_ASIO_CHECK(ex_one_prop_10.target<void>() == 0);
283   BOOST_ASIO_CHECK(ex_one_prop_10 == null_ptr);
284   BOOST_ASIO_CHECK(ex_one_prop_1.target<void>() == 0);
285   BOOST_ASIO_CHECK(ex_one_prop_1 == null_ptr);
286 
287   ex_one_prop_t ex_one_prop_11(std::move(ex_one_prop_3));
288 
289   BOOST_ASIO_CHECK(ex_one_prop_11.target<void>() != 0);
290   BOOST_ASIO_CHECK(ex_one_prop_11 != null_ptr);
291   BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() == 0);
292   BOOST_ASIO_CHECK(ex_one_prop_3 == null_ptr);
293   BOOST_ASIO_CHECK(ex_one_prop_11 == ex_one_prop_5);
294 
295   ex_one_prop_t ex_one_prop_12(std::move(ex_one_prop_7));
296 
297   BOOST_ASIO_CHECK(ex_one_prop_12.target<void>() != 0);
298   BOOST_ASIO_CHECK(ex_one_prop_12 != null_ptr);
299   BOOST_ASIO_CHECK(ex_one_prop_7.target<void>() == 0);
300   BOOST_ASIO_CHECK(ex_one_prop_7 == null_ptr);
301   BOOST_ASIO_CHECK(ex_one_prop_12 == ex_one_prop_6);
302   BOOST_ASIO_CHECK(ex_one_prop_12 != ex_one_prop_8);
303 #endif // defined(BOOST_ASIO_HAS_MOVE)
304 
305   ex_one_prop_t ex_one_prop_13(ex_two_props_1);
306 
307   BOOST_ASIO_CHECK(ex_one_prop_13.target<void>() == 0);
308   BOOST_ASIO_CHECK(ex_one_prop_13 == null_ptr);
309 
310   ex_one_prop_t ex_one_prop_14(ex_two_props_5);
311 
312   BOOST_ASIO_CHECK(ex_one_prop_14.target<void>() != 0);
313   BOOST_ASIO_CHECK(ex_one_prop_14 != null_ptr);
314 
315   ex_one_prop_t ex_one_prop_15(ex_two_props_9);
316 
317   BOOST_ASIO_CHECK(ex_one_prop_15.target<void>() != 0);
318   BOOST_ASIO_CHECK(ex_one_prop_15 != null_ptr);
319 
320   ex_no_props_t ex_no_props_1;
321 
322   BOOST_ASIO_CHECK(ex_no_props_1.target<void>() == 0);
323   BOOST_ASIO_CHECK(ex_no_props_1 == null_ptr);
324 
325   ex_no_props_t ex_no_props_2(null_ptr);
326 
327   BOOST_ASIO_CHECK(ex_no_props_2.target<void>() == 0);
328   BOOST_ASIO_CHECK(ex_no_props_2 == null_ptr);
329   BOOST_ASIO_CHECK(ex_no_props_2 == ex_no_props_1);
330 
331   ex_no_props_t ex_no_props_3(pool.executor());
332 
333   BOOST_ASIO_CHECK(ex_no_props_3.target<void>() != 0);
334   BOOST_ASIO_CHECK(ex_no_props_3 != null_ptr);
335   BOOST_ASIO_CHECK(ex_no_props_3 != ex_no_props_1);
336 
337   ex_no_props_t ex_no_props_4(ex_no_props_1);
338 
339   BOOST_ASIO_CHECK(ex_no_props_4.target<void>() == 0);
340   BOOST_ASIO_CHECK(ex_no_props_4 == null_ptr);
341   BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_1);
342 
343   ex_no_props_t ex_no_props_5(ex_no_props_3);
344 
345   BOOST_ASIO_CHECK(ex_no_props_5.target<void>() != 0);
346   BOOST_ASIO_CHECK(ex_no_props_5 != null_ptr);
347   BOOST_ASIO_CHECK(ex_no_props_5 == ex_no_props_3);
348 
349   ex_no_props_t ex_no_props_6 = fat_executor(1);
350 
351   BOOST_ASIO_CHECK(ex_no_props_6.target<void>() != 0);
352   BOOST_ASIO_CHECK(ex_no_props_6 != null_ptr);
353   BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_1);
354 
355   ex_no_props_t ex_no_props_7 = fat_executor(1);
356 
357   BOOST_ASIO_CHECK(ex_no_props_7.target<void>() != 0);
358   BOOST_ASIO_CHECK(ex_no_props_7 != null_ptr);
359   BOOST_ASIO_CHECK(ex_no_props_7 != ex_no_props_1);
360   BOOST_ASIO_CHECK(ex_no_props_7 == ex_no_props_6);
361 
362   ex_no_props_t ex_no_props_8 = fat_executor(2);
363 
364   BOOST_ASIO_CHECK(ex_no_props_8.target<void>() != 0);
365   BOOST_ASIO_CHECK(ex_no_props_8 != null_ptr);
366   BOOST_ASIO_CHECK(ex_no_props_8 != ex_no_props_1);
367   BOOST_ASIO_CHECK(ex_no_props_8 != ex_no_props_6);
368   BOOST_ASIO_CHECK(ex_no_props_8 != ex_no_props_7);
369 
370   ex_no_props_t ex_no_props_9(ex_no_props_6);
371 
372   BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
373   BOOST_ASIO_CHECK(ex_no_props_9 != null_ptr);
374   BOOST_ASIO_CHECK(ex_no_props_9 != ex_no_props_1);
375   BOOST_ASIO_CHECK(ex_no_props_9 == ex_no_props_6);
376   BOOST_ASIO_CHECK(ex_no_props_9 == ex_no_props_7);
377   BOOST_ASIO_CHECK(ex_no_props_9 != ex_no_props_8);
378 
379 #if defined(BOOST_ASIO_HAS_MOVE)
380   ex_no_props_t ex_no_props_10(std::move(ex_no_props_1));
381 
382   BOOST_ASIO_CHECK(ex_no_props_10.target<void>() == 0);
383   BOOST_ASIO_CHECK(ex_no_props_10 == null_ptr);
384   BOOST_ASIO_CHECK(ex_no_props_1.target<void>() == 0);
385   BOOST_ASIO_CHECK(ex_no_props_1 == null_ptr);
386 
387   ex_no_props_t ex_no_props_11(std::move(ex_no_props_3));
388 
389   BOOST_ASIO_CHECK(ex_no_props_11.target<void>() != 0);
390   BOOST_ASIO_CHECK(ex_no_props_11 != null_ptr);
391   BOOST_ASIO_CHECK(ex_no_props_3.target<void>() == 0);
392   BOOST_ASIO_CHECK(ex_no_props_3 == null_ptr);
393   BOOST_ASIO_CHECK(ex_no_props_11 == ex_no_props_5);
394 
395   ex_no_props_t ex_no_props_12(std::move(ex_no_props_7));
396 
397   BOOST_ASIO_CHECK(ex_no_props_12.target<void>() != 0);
398   BOOST_ASIO_CHECK(ex_no_props_12 != null_ptr);
399   BOOST_ASIO_CHECK(ex_no_props_7.target<void>() == 0);
400   BOOST_ASIO_CHECK(ex_no_props_7 == null_ptr);
401   BOOST_ASIO_CHECK(ex_no_props_12 == ex_no_props_6);
402   BOOST_ASIO_CHECK(ex_no_props_12 != ex_no_props_8);
403 #endif // defined(BOOST_ASIO_HAS_MOVE)
404 
405   ex_no_props_t ex_no_props_13(ex_two_props_1);
406 
407   BOOST_ASIO_CHECK(ex_no_props_13.target<void>() == 0);
408   BOOST_ASIO_CHECK(ex_no_props_13 == null_ptr);
409 
410   ex_no_props_t ex_no_props_14(ex_two_props_5);
411 
412   BOOST_ASIO_CHECK(ex_no_props_14.target<void>() != 0);
413   BOOST_ASIO_CHECK(ex_no_props_14 != null_ptr);
414 
415   ex_no_props_t ex_no_props_15(ex_two_props_9);
416 
417   BOOST_ASIO_CHECK(ex_no_props_15.target<void>() != 0);
418   BOOST_ASIO_CHECK(ex_no_props_15 != null_ptr);
419 
420   ex_no_props_t ex_no_props_16(ex_one_prop_1);
421 
422   BOOST_ASIO_CHECK(ex_no_props_16.target<void>() == 0);
423   BOOST_ASIO_CHECK(ex_no_props_16 == null_ptr);
424 
425   ex_no_props_t ex_no_props_17(ex_one_prop_5);
426 
427   BOOST_ASIO_CHECK(ex_no_props_17.target<void>() != 0);
428   BOOST_ASIO_CHECK(ex_no_props_17 != null_ptr);
429 
430   ex_no_props_t ex_no_props_18(ex_one_prop_9);
431 
432   BOOST_ASIO_CHECK(ex_no_props_18.target<void>() != 0);
433   BOOST_ASIO_CHECK(ex_no_props_18 != null_ptr);
434 }
435 
any_executor_assignment_test()436 void any_executor_assignment_test()
437 {
438   typedef execution::any_executor<> ex_no_props_t;
439 
440   typedef execution::any_executor<
441       execution::blocking_t
442     > ex_one_prop_t;
443 
444   typedef execution::any_executor<
445       execution::blocking_t,
446       execution::occupancy_t
447     > ex_two_props_t;
448 
449   thread_pool pool(1);
450   boost::asio::nullptr_t null_ptr = boost::asio::nullptr_t();
451 
452   ex_two_props_t ex_two_props_1;
453 
454   ex_two_props_t ex_two_props_2;
455   ex_two_props_2 = null_ptr;
456 
457   BOOST_ASIO_CHECK(ex_two_props_2.target<void>() == 0);
458 
459   ex_two_props_t ex_two_props_3;
460   ex_two_props_3 = pool.executor();
461 
462   BOOST_ASIO_CHECK(ex_two_props_3.target<void>() != 0);
463 
464   ex_two_props_t ex_two_props_4;
465   ex_two_props_4 = ex_two_props_1;
466 
467   BOOST_ASIO_CHECK(ex_two_props_4.target<void>() == 0);
468   BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_1);
469 
470   ex_two_props_4 = ex_two_props_3;
471 
472   BOOST_ASIO_CHECK(ex_two_props_4.target<void>() != 0);
473   BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_3);
474 
475   ex_two_props_t ex_two_props_5;
476   ex_two_props_5 = fat_executor(1);
477 
478   BOOST_ASIO_CHECK(ex_two_props_5.target<void>() != 0);
479   BOOST_ASIO_CHECK(ex_two_props_5 != null_ptr);
480   BOOST_ASIO_CHECK(ex_two_props_5 != ex_two_props_1);
481 
482   ex_two_props_t ex_two_props_6;
483   ex_two_props_6 = fat_executor(1);
484 
485   BOOST_ASIO_CHECK(ex_two_props_6.target<void>() != 0);
486   BOOST_ASIO_CHECK(ex_two_props_6 != null_ptr);
487   BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_1);
488   BOOST_ASIO_CHECK(ex_two_props_6 == ex_two_props_5);
489 
490   ex_two_props_6 = fat_executor(2);
491 
492   BOOST_ASIO_CHECK(ex_two_props_6.target<void>() != 0);
493   BOOST_ASIO_CHECK(ex_two_props_6 != null_ptr);
494   BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_1);
495   BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_5);
496 
497   ex_two_props_t ex_two_props_7;
498   ex_two_props_7 = ex_two_props_5;
499 
500   BOOST_ASIO_CHECK(ex_two_props_7.target<void>() != 0);
501   BOOST_ASIO_CHECK(ex_two_props_7 != null_ptr);
502   BOOST_ASIO_CHECK(ex_two_props_7 != ex_two_props_1);
503   BOOST_ASIO_CHECK(ex_two_props_7 == ex_two_props_5);
504   BOOST_ASIO_CHECK(ex_two_props_7 != ex_two_props_6);
505 
506 #if defined(BOOST_ASIO_HAS_MOVE)
507   ex_two_props_t ex_two_props_8;
508   ex_two_props_8 = std::move(ex_two_props_1);
509 
510   BOOST_ASIO_CHECK(ex_two_props_8.target<void>() == 0);
511   BOOST_ASIO_CHECK(ex_two_props_1.target<void>() == 0);
512 
513   ex_two_props_8 = std::move(ex_two_props_3);
514 
515   BOOST_ASIO_CHECK(ex_two_props_8.target<void>() != 0);
516   BOOST_ASIO_CHECK(ex_two_props_3.target<void>() == 0);
517   BOOST_ASIO_CHECK(ex_two_props_8 == ex_two_props_4);
518 
519   ex_two_props_8 = std::move(ex_two_props_5);
520 
521   BOOST_ASIO_CHECK(ex_two_props_8.target<void>() != 0);
522   BOOST_ASIO_CHECK(ex_two_props_5.target<void>() == 0);
523   BOOST_ASIO_CHECK(ex_two_props_8 == ex_two_props_7);
524 #endif // defined(BOOST_ASIO_HAS_MOVE)
525 
526   ex_one_prop_t ex_one_prop_1;
527 
528   ex_one_prop_t ex_one_prop_2;
529   ex_one_prop_2 = null_ptr;
530 
531   BOOST_ASIO_CHECK(ex_one_prop_2.target<void>() == 0);
532 
533   ex_one_prop_t ex_one_prop_3;
534   ex_one_prop_3 = pool.executor();
535 
536   BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() != 0);
537 
538   ex_one_prop_t ex_one_prop_4;
539   ex_one_prop_4 = ex_one_prop_1;
540 
541   BOOST_ASIO_CHECK(ex_one_prop_4.target<void>() == 0);
542   BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_1);
543 
544   ex_one_prop_4 = ex_one_prop_3;
545 
546   BOOST_ASIO_CHECK(ex_one_prop_4.target<void>() != 0);
547   BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_3);
548 
549   ex_one_prop_t ex_one_prop_5;
550   ex_one_prop_5 = fat_executor(1);
551 
552   BOOST_ASIO_CHECK(ex_one_prop_5.target<void>() != 0);
553   BOOST_ASIO_CHECK(ex_one_prop_5 != null_ptr);
554   BOOST_ASIO_CHECK(ex_one_prop_5 != ex_one_prop_1);
555 
556   ex_one_prop_t ex_one_prop_6;
557   ex_one_prop_6 = fat_executor(1);
558 
559   BOOST_ASIO_CHECK(ex_one_prop_6.target<void>() != 0);
560   BOOST_ASIO_CHECK(ex_one_prop_6 != null_ptr);
561   BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_1);
562   BOOST_ASIO_CHECK(ex_one_prop_6 == ex_one_prop_5);
563 
564   ex_one_prop_6 = fat_executor(2);
565 
566   BOOST_ASIO_CHECK(ex_one_prop_6.target<void>() != 0);
567   BOOST_ASIO_CHECK(ex_one_prop_6 != null_ptr);
568   BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_1);
569   BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_5);
570 
571   ex_one_prop_t ex_one_prop_7;
572   ex_one_prop_7 = ex_one_prop_5;
573 
574   BOOST_ASIO_CHECK(ex_one_prop_7.target<void>() != 0);
575   BOOST_ASIO_CHECK(ex_one_prop_7 != null_ptr);
576   BOOST_ASIO_CHECK(ex_one_prop_7 != ex_one_prop_1);
577   BOOST_ASIO_CHECK(ex_one_prop_7 == ex_one_prop_5);
578   BOOST_ASIO_CHECK(ex_one_prop_7 != ex_one_prop_6);
579 
580 #if defined(BOOST_ASIO_HAS_MOVE)
581   ex_one_prop_t ex_one_prop_8;
582   ex_one_prop_8 = std::move(ex_one_prop_1);
583 
584   BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() == 0);
585   BOOST_ASIO_CHECK(ex_one_prop_1.target<void>() == 0);
586 
587   ex_one_prop_8 = std::move(ex_one_prop_3);
588 
589   BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() != 0);
590   BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() == 0);
591   BOOST_ASIO_CHECK(ex_one_prop_8 == ex_one_prop_4);
592 
593   ex_one_prop_8 = std::move(ex_one_prop_5);
594 
595   BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() != 0);
596   BOOST_ASIO_CHECK(ex_one_prop_5.target<void>() == 0);
597   BOOST_ASIO_CHECK(ex_one_prop_8 == ex_one_prop_7);
598 #endif // defined(BOOST_ASIO_HAS_MOVE)
599 
600   ex_one_prop_t ex_one_prop_9;
601   ex_one_prop_9 = ex_two_props_1;
602 
603   BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() == 0);
604 
605   ex_one_prop_9 = ex_two_props_4;
606 
607   BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() != 0);
608 
609   ex_one_prop_9 = ex_two_props_7;
610 
611   BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() != 0);
612 
613   ex_no_props_t ex_no_props_1;
614 
615   ex_no_props_t ex_no_props_2;
616   ex_no_props_2 = null_ptr;
617 
618   BOOST_ASIO_CHECK(ex_no_props_2.target<void>() == 0);
619 
620   ex_no_props_t ex_no_props_3;
621   ex_no_props_3 = pool.executor();
622 
623   BOOST_ASIO_CHECK(ex_no_props_3.target<void>() != 0);
624 
625   ex_no_props_t ex_no_props_4;
626   ex_no_props_4 = ex_no_props_1;
627 
628   BOOST_ASIO_CHECK(ex_no_props_4.target<void>() == 0);
629   BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_1);
630 
631   ex_no_props_4 = ex_no_props_3;
632 
633   BOOST_ASIO_CHECK(ex_no_props_4.target<void>() != 0);
634   BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_3);
635 
636   ex_no_props_t ex_no_props_5;
637   ex_no_props_5 = fat_executor(1);
638 
639   BOOST_ASIO_CHECK(ex_no_props_5.target<void>() != 0);
640   BOOST_ASIO_CHECK(ex_no_props_5 != null_ptr);
641   BOOST_ASIO_CHECK(ex_no_props_5 != ex_no_props_1);
642 
643   ex_no_props_t ex_no_props_6;
644   ex_no_props_6 = fat_executor(1);
645 
646   BOOST_ASIO_CHECK(ex_no_props_6.target<void>() != 0);
647   BOOST_ASIO_CHECK(ex_no_props_6 != null_ptr);
648   BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_1);
649   BOOST_ASIO_CHECK(ex_no_props_6 == ex_no_props_5);
650 
651   ex_no_props_6 = fat_executor(2);
652 
653   BOOST_ASIO_CHECK(ex_no_props_6.target<void>() != 0);
654   BOOST_ASIO_CHECK(ex_no_props_6 != null_ptr);
655   BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_1);
656   BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_5);
657 
658   ex_no_props_t ex_no_props_7;
659   ex_no_props_7 = ex_no_props_5;
660 
661   BOOST_ASIO_CHECK(ex_no_props_7.target<void>() != 0);
662   BOOST_ASIO_CHECK(ex_no_props_7 != null_ptr);
663   BOOST_ASIO_CHECK(ex_no_props_7 != ex_no_props_1);
664   BOOST_ASIO_CHECK(ex_no_props_7 == ex_no_props_5);
665   BOOST_ASIO_CHECK(ex_no_props_7 != ex_no_props_6);
666 
667 #if defined(BOOST_ASIO_HAS_MOVE)
668   ex_no_props_t ex_no_props_8;
669   ex_no_props_8 = std::move(ex_no_props_1);
670 
671   BOOST_ASIO_CHECK(ex_no_props_8.target<void>() == 0);
672   BOOST_ASIO_CHECK(ex_no_props_1.target<void>() == 0);
673 
674   ex_no_props_8 = std::move(ex_no_props_3);
675 
676   BOOST_ASIO_CHECK(ex_no_props_8.target<void>() != 0);
677   BOOST_ASIO_CHECK(ex_no_props_3.target<void>() == 0);
678   BOOST_ASIO_CHECK(ex_no_props_8 == ex_no_props_4);
679 
680   ex_no_props_8 = std::move(ex_no_props_5);
681 
682   BOOST_ASIO_CHECK(ex_no_props_8.target<void>() != 0);
683   BOOST_ASIO_CHECK(ex_no_props_5.target<void>() == 0);
684   BOOST_ASIO_CHECK(ex_no_props_8 == ex_no_props_7);
685 #endif // defined(BOOST_ASIO_HAS_MOVE)
686 
687   ex_no_props_t ex_no_props_9;
688   ex_no_props_9 = ex_two_props_1;
689 
690   BOOST_ASIO_CHECK(ex_no_props_9.target<void>() == 0);
691 
692   ex_no_props_9 = ex_two_props_4;
693 
694   BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
695 
696   ex_no_props_9 = ex_two_props_7;
697 
698   BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
699 
700   ex_no_props_9 = ex_one_prop_1;
701 
702   BOOST_ASIO_CHECK(ex_no_props_9.target<void>() == 0);
703 
704   ex_no_props_9 = ex_one_prop_4;
705 
706   BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
707 
708   ex_no_props_9 = ex_one_prop_7;
709 
710   BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
711 }
712 
any_executor_swap_test()713 void any_executor_swap_test()
714 {
715   typedef execution::any_executor<> ex_no_props_t;
716 
717   typedef execution::any_executor<
718       execution::blocking_t
719     > ex_one_prop_t;
720 
721   typedef execution::any_executor<
722       execution::blocking_t,
723       execution::occupancy_t
724     > ex_two_props_t;
725 
726   thread_pool pool1(1);
727   thread_pool pool2(1);
728 
729   ex_no_props_t ex_no_props_1(pool1.executor());
730   ex_no_props_t ex_no_props_2(pool2.executor());
731 
732   ex_no_props_t ex_no_props_3(ex_no_props_1);
733   ex_no_props_t ex_no_props_4(ex_no_props_2);
734 
735   BOOST_ASIO_CHECK(ex_no_props_3 == ex_no_props_1);
736   BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_2);
737 
738   ex_no_props_3.swap(ex_no_props_4);
739 
740   BOOST_ASIO_CHECK(ex_no_props_3 == ex_no_props_2);
741   BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_1);
742 
743   execution::swap(ex_no_props_3, ex_no_props_4);
744 
745   BOOST_ASIO_CHECK(ex_no_props_3 == ex_no_props_1);
746   BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_2);
747 
748   ex_one_prop_t ex_one_prop_1(pool1.executor());
749   ex_one_prop_t ex_one_prop_2(pool2.executor());
750 
751   ex_one_prop_t ex_one_prop_3(ex_one_prop_1);
752   ex_one_prop_t ex_one_prop_4(ex_one_prop_2);
753 
754   BOOST_ASIO_CHECK(ex_one_prop_3 == ex_one_prop_1);
755   BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_2);
756 
757   ex_one_prop_3.swap(ex_one_prop_4);
758 
759   BOOST_ASIO_CHECK(ex_one_prop_3 == ex_one_prop_2);
760   BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_1);
761 
762   execution::swap(ex_one_prop_3, ex_one_prop_4);
763 
764   BOOST_ASIO_CHECK(ex_one_prop_3 == ex_one_prop_1);
765   BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_2);
766 
767   ex_two_props_t ex_two_props_1(pool1.executor());
768   ex_two_props_t ex_two_props_2(pool2.executor());
769 
770   ex_two_props_t ex_two_props_3(ex_two_props_1);
771   ex_two_props_t ex_two_props_4(ex_two_props_2);
772 
773   BOOST_ASIO_CHECK(ex_two_props_3 == ex_two_props_1);
774   BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_2);
775 
776   ex_two_props_3.swap(ex_two_props_4);
777 
778   BOOST_ASIO_CHECK(ex_two_props_3 == ex_two_props_2);
779   BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_1);
780 
781   execution::swap(ex_two_props_3, ex_two_props_4);
782 
783   BOOST_ASIO_CHECK(ex_two_props_3 == ex_two_props_1);
784   BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_2);
785 }
786 
any_executor_query_test()787 void any_executor_query_test()
788 {
789   thread_pool pool(1);
790   execution::any_executor<
791       execution::blocking_t,
792       execution::outstanding_work_t,
793       execution::relationship_t,
794       execution::mapping_t::thread_t,
795       execution::occupancy_t>
796     ex(pool.executor());
797 
798   BOOST_ASIO_CHECK(
799       boost::asio::query(ex, boost::asio::execution::blocking)
800         == boost::asio::execution::blocking.possibly);
801 
802   BOOST_ASIO_CHECK(
803       boost::asio::query(ex, boost::asio::execution::blocking.possibly)
804         == boost::asio::execution::blocking.possibly);
805 
806   BOOST_ASIO_CHECK(
807       boost::asio::query(ex, boost::asio::execution::outstanding_work)
808         == boost::asio::execution::outstanding_work.untracked);
809 
810   BOOST_ASIO_CHECK(
811       boost::asio::query(ex, boost::asio::execution::outstanding_work.untracked)
812         == boost::asio::execution::outstanding_work.untracked);
813 
814   BOOST_ASIO_CHECK(
815       boost::asio::query(ex, boost::asio::execution::relationship)
816         == boost::asio::execution::relationship.fork);
817 
818   BOOST_ASIO_CHECK(
819       boost::asio::query(ex, boost::asio::execution::relationship.fork)
820         == boost::asio::execution::relationship.fork);
821 
822   BOOST_ASIO_CHECK(
823       boost::asio::query(ex, boost::asio::execution::mapping)
824         == boost::asio::execution::mapping.thread);
825 
826   BOOST_ASIO_CHECK(
827       boost::asio::query(ex, boost::asio::execution::occupancy)
828         == 1);
829 }
830 
any_executor_execute_test()831 void any_executor_execute_test()
832 {
833   int count = 0;
834   thread_pool pool(1);
835   execution::any_executor<
836       execution::blocking_t::possibly_t,
837       execution::blocking_t::never_t,
838       execution::outstanding_work_t::untracked_t,
839       execution::outstanding_work_t::tracked_t,
840       execution::relationship_t::continuation_t>
841     ex(pool.executor());
842 
843   boost::asio::execution::execute(pool.executor(),
844       bindns::bind(increment, &count));
845 
846   boost::asio::execution::execute(
847       boost::asio::require(pool.executor(),
848         boost::asio::execution::blocking.possibly),
849       bindns::bind(increment, &count));
850 
851   boost::asio::execution::execute(
852       boost::asio::require(pool.executor(),
853         boost::asio::execution::blocking.never),
854       bindns::bind(increment, &count));
855 
856   boost::asio::execution::execute(
857       boost::asio::require(pool.executor(),
858         boost::asio::execution::blocking.never,
859         boost::asio::execution::outstanding_work.tracked),
860       bindns::bind(increment, &count));
861 
862   boost::asio::execution::execute(
863       boost::asio::require(pool.executor(),
864         boost::asio::execution::blocking.never,
865         boost::asio::execution::outstanding_work.untracked),
866       bindns::bind(increment, &count));
867 
868   boost::asio::execution::execute(
869       boost::asio::require(pool.executor(),
870         boost::asio::execution::blocking.never,
871         boost::asio::execution::outstanding_work.untracked,
872         boost::asio::execution::relationship.continuation),
873       bindns::bind(increment, &count));
874 
875   pool.wait();
876 
877   BOOST_ASIO_CHECK(count == 6);
878 }
879 
880 BOOST_ASIO_TEST_SUITE
881 (
882   "any_executor",
883   BOOST_ASIO_TEST_CASE(any_executor_construction_test)
884   BOOST_ASIO_TEST_CASE(any_executor_assignment_test)
885   BOOST_ASIO_TEST_CASE(any_executor_swap_test)
886   BOOST_ASIO_TEST_CASE(any_executor_query_test)
887   BOOST_ASIO_TEST_CASE(any_executor_execute_test)
888 )
889