• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // submit.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/submit.hpp>
18 
19 #include <boost/system/error_code.hpp>
20 #include "../unit_test.hpp"
21 
22 namespace exec = boost::asio::execution;
23 
24 static int call_count = 0;
25 
26 struct operation_state
27 {
startoperation_state28   void start() BOOST_ASIO_NOEXCEPT
29   {
30   }
31 };
32 
33 namespace boost {
34 namespace asio {
35 namespace traits {
36 
37 #if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
38 
39 template <>
40 struct start_member<operation_state>
41 {
42   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
43   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
44   typedef void result_type;
45 };
46 
47 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
48 
49 } // namespace traits
50 } // namespace asio
51 } // namespace boost
52 
53 struct no_submit_1
54 {
55 };
56 
57 struct no_submit_2 : exec::sender_base
58 {
59 };
60 
61 struct no_submit_3
62 {
63   template <typename R>
submitno_submit_364   void submit(BOOST_ASIO_MOVE_ARG(R) r)
65   {
66     (void)r;
67   }
68 };
69 
70 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
71 
72 namespace boost {
73 namespace asio {
74 namespace traits {
75 
76 template <typename R>
77 struct submit_member<no_submit_3, R>
78 {
79   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
80   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
81   typedef void result_type;
82 };
83 
84 } // namespace traits
85 } // namespace asio
86 } // namespace boost
87 
88 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
89 
90 struct const_member_submit : exec::sender_base
91 {
const_member_submitconst_member_submit92   const_member_submit()
93   {
94   }
95 
96   template <typename R>
connectconst_member_submit97   operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
98   {
99     (void)r;
100     return operation_state();
101   }
102 
103   template <typename R>
submitconst_member_submit104   void submit(BOOST_ASIO_MOVE_ARG(R) r) const
105   {
106     (void)r;
107     ++call_count;
108   }
109 };
110 
111 namespace boost {
112 namespace asio {
113 namespace traits {
114 
115 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
116 
117 template <typename R>
118 struct connect_member<const const_member_submit, R>
119 {
120   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
121   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
122   typedef operation_state result_type;
123 };
124 
125 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
126 
127 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
128 
129 template <typename R>
130 struct submit_member<const const_member_submit, R>
131 {
132   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
133   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
134   typedef void result_type;
135 };
136 
137 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
138 
139 } // namespace traits
140 } // namespace asio
141 } // namespace boost
142 
143 struct free_submit_const_receiver : exec::sender_base
144 {
free_submit_const_receiverfree_submit_const_receiver145   free_submit_const_receiver()
146   {
147   }
148 
149   template <typename R>
connect(const free_submit_const_receiver &,BOOST_ASIO_MOVE_ARG (R)r)150   friend operation_state connect(
151       const free_submit_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
152   {
153     (void)r;
154     return operation_state();
155   }
156 
157   template <typename R>
submit(const free_submit_const_receiver &,BOOST_ASIO_MOVE_ARG (R)r)158   friend void submit(
159       const free_submit_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
160   {
161     (void)r;
162     ++call_count;
163   }
164 };
165 
166 namespace boost {
167 namespace asio {
168 namespace traits {
169 
170 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
171 
172 template <typename R>
173 struct connect_free<const free_submit_const_receiver, R>
174 {
175   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
176   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
177   typedef operation_state result_type;
178 };
179 
180 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
181 
182 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
183 
184 template <typename R>
185 struct submit_free<const free_submit_const_receiver, R>
186 {
187   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
188   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
189   typedef void result_type;
190 };
191 
192 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
193 
194 } // namespace traits
195 } // namespace asio
196 } // namespace boost
197 
198 struct non_const_member_submit : exec::sender_base
199 {
non_const_member_submitnon_const_member_submit200   non_const_member_submit()
201   {
202   }
203 
204   template <typename R>
connectnon_const_member_submit205   operation_state connect(BOOST_ASIO_MOVE_ARG(R) r)
206   {
207     (void)r;
208     return operation_state();
209   }
210 
211   template <typename R>
submitnon_const_member_submit212   void submit(BOOST_ASIO_MOVE_ARG(R) r)
213   {
214     (void)r;
215     ++call_count;
216   }
217 };
218 
219 namespace boost {
220 namespace asio {
221 namespace traits {
222 
223 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
224 
225 template <typename R>
226 struct connect_member<non_const_member_submit, R>
227 {
228   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
229   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
230   typedef operation_state result_type;
231 };
232 
233 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
234 
235 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
236 
237 template <typename R>
238 struct submit_member<non_const_member_submit, R>
239 {
240   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
241   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
242   typedef void result_type;
243 };
244 
245 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
246 
247 } // namespace traits
248 } // namespace asio
249 } // namespace boost
250 
251 struct free_submit_non_const_receiver : exec::sender_base
252 {
free_submit_non_const_receiverfree_submit_non_const_receiver253   free_submit_non_const_receiver()
254   {
255   }
256 
257   template <typename R>
connect(free_submit_non_const_receiver &,BOOST_ASIO_MOVE_ARG (R)r)258   friend operation_state connect(
259       free_submit_non_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
260   {
261     (void)r;
262     return operation_state();
263   }
264 
265   template <typename R>
submit(free_submit_non_const_receiver &,BOOST_ASIO_MOVE_ARG (R)r)266   friend void submit(
267       free_submit_non_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
268   {
269     (void)r;
270     ++call_count;
271   }
272 };
273 
274 namespace boost {
275 namespace asio {
276 namespace traits {
277 
278 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
279 
280 template <typename R>
281 struct connect_free<free_submit_non_const_receiver, R>
282 {
283   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
284   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
285   typedef operation_state result_type;
286 };
287 
288 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
289 
290 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
291 
292 template <typename R>
293 struct submit_free<free_submit_non_const_receiver, R>
294 {
295   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
296   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
297   typedef void result_type;
298 };
299 
300 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
301 
302 } // namespace traits
303 } // namespace asio
304 } // namespace boost
305 
306 struct receiver
307 {
receiverreceiver308   receiver()
309   {
310   }
311 
receiverreceiver312   receiver(const receiver&)
313   {
314   }
315 
316 #if defined(BOOST_ASIO_HAS_MOVE)
receiverreceiver317   receiver(receiver&&) BOOST_ASIO_NOEXCEPT
318   {
319   }
320 #endif // defined(BOOST_ASIO_HAS_MOVE)
321 
322   template <typename E>
set_errorreceiver323   void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
324   {
325     (void)e;
326   }
327 
set_donereceiver328   void set_done() BOOST_ASIO_NOEXCEPT
329   {
330   }
331 };
332 
333 namespace boost {
334 namespace asio {
335 namespace traits {
336 
337 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
338 
339 template <typename E>
340 struct set_error_member<receiver, E>
341 {
342   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
343   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
344   typedef void result_type;
345 };
346 
347 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
348 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
349 
350 template <>
351 struct set_done_member<receiver>
352 {
353   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
354   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
355   typedef void result_type;
356 };
357 
358 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
359 
360 } // namespace traits
361 } // namespace asio
362 } // namespace boost
363 
364 struct executor
365 {
executorexecutor366   executor()
367   {
368   }
369 
executorexecutor370   executor(const executor&) BOOST_ASIO_NOEXCEPT
371   {
372   }
373 
374 #if defined(BOOST_ASIO_HAS_MOVE)
executorexecutor375   executor(executor&&) BOOST_ASIO_NOEXCEPT
376   {
377   }
378 #endif // defined(BOOST_ASIO_HAS_MOVE)
379 
380   template <typename F>
executeexecutor381   void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
382   {
383     (void)f;
384     ++call_count;
385   }
386 
operator ==executor387   bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
388   {
389     return true;
390   }
391 
operator !=executor392   bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
393   {
394     return false;
395   }
396 };
397 
398 namespace boost {
399 namespace asio {
400 namespace traits {
401 
402 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
403 
404 template <typename F>
405 struct execute_member<executor, F>
406 {
407   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
408   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
409   typedef void result_type;
410 };
411 
412 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
413 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
414 
415 template <>
416 struct equality_comparable<executor>
417 {
418   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
419   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
420 };
421 
422 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
423 
424 } // namespace traits
425 } // namespace asio
426 } // namespace boost
427 
test_can_submit()428 void test_can_submit()
429 {
430   BOOST_ASIO_CONSTEXPR bool b1 = exec::can_submit<
431       no_submit_1&, receiver>::value;
432   BOOST_ASIO_CHECK(b1 == false);
433 
434   BOOST_ASIO_CONSTEXPR bool b2 = exec::can_submit<
435       const no_submit_1&, receiver>::value;
436   BOOST_ASIO_CHECK(b2 == false);
437 
438   BOOST_ASIO_CONSTEXPR bool b3 = exec::can_submit<
439       no_submit_2&, receiver>::value;
440   BOOST_ASIO_CHECK(b3 == false);
441 
442   BOOST_ASIO_CONSTEXPR bool b4 = exec::can_submit<
443       const no_submit_2&, receiver>::value;
444   BOOST_ASIO_CHECK(b4 == false);
445 
446   BOOST_ASIO_CONSTEXPR bool b5 = exec::can_submit<
447       no_submit_3&, receiver>::value;
448   BOOST_ASIO_CHECK(b5 == false);
449 
450   BOOST_ASIO_CONSTEXPR bool b6 = exec::can_submit<
451       const no_submit_3&, receiver>::value;
452   BOOST_ASIO_CHECK(b6 == false);
453 
454   BOOST_ASIO_CONSTEXPR bool b7 = exec::can_submit<
455       const_member_submit&, receiver>::value;
456   BOOST_ASIO_CHECK(b7 == true);
457 
458   BOOST_ASIO_CONSTEXPR bool b8 = exec::can_submit<
459       const const_member_submit&, receiver>::value;
460   BOOST_ASIO_CHECK(b8 == true);
461 
462   BOOST_ASIO_CONSTEXPR bool b9 = exec::can_submit<
463       free_submit_const_receiver&, receiver>::value;
464   BOOST_ASIO_CHECK(b9 == true);
465 
466   BOOST_ASIO_CONSTEXPR bool b10 = exec::can_submit<
467       const free_submit_const_receiver&, receiver>::value;
468   BOOST_ASIO_CHECK(b10 == true);
469 
470   BOOST_ASIO_CONSTEXPR bool b11 = exec::can_submit<
471       non_const_member_submit&, receiver>::value;
472   BOOST_ASIO_CHECK(b11 == true);
473 
474   BOOST_ASIO_CONSTEXPR bool b12 = exec::can_submit<
475       const non_const_member_submit&, receiver>::value;
476   BOOST_ASIO_CHECK(b12 == false);
477 
478   BOOST_ASIO_CONSTEXPR bool b13 = exec::can_submit<
479       free_submit_non_const_receiver&, receiver>::value;
480   BOOST_ASIO_CHECK(b13 == true);
481 
482   BOOST_ASIO_CONSTEXPR bool b14 = exec::can_submit<
483       const free_submit_non_const_receiver&, receiver>::value;
484   BOOST_ASIO_CHECK(b14 == false);
485 
486   BOOST_ASIO_CONSTEXPR bool b15 = exec::can_submit<
487       executor&, receiver>::value;
488   BOOST_ASIO_CHECK(b15 == true);
489 
490   BOOST_ASIO_CONSTEXPR bool b16 = exec::can_submit<
491       const executor&, receiver>::value;
492   BOOST_ASIO_CHECK(b16 == true);
493 }
494 
increment(int * count)495 void increment(int* count)
496 {
497   ++(*count);
498 }
499 
test_submit()500 void test_submit()
501 {
502   receiver r;
503 
504   call_count = 0;
505   const_member_submit s1;
506   exec::submit(s1, r);
507   BOOST_ASIO_CHECK(call_count == 1);
508 
509   call_count = 0;
510   const const_member_submit s2;
511   exec::submit(s2, r);
512   BOOST_ASIO_CHECK(call_count == 1);
513 
514   call_count = 0;
515   exec::submit(const_member_submit(), r);
516   BOOST_ASIO_CHECK(call_count == 1);
517 
518   call_count = 0;
519   free_submit_const_receiver s3;
520   exec::submit(s3, r);
521   BOOST_ASIO_CHECK(call_count == 1);
522 
523   call_count = 0;
524   const free_submit_const_receiver s4;
525   exec::submit(s4, r);
526   BOOST_ASIO_CHECK(call_count == 1);
527 
528   call_count = 0;
529   exec::submit(free_submit_const_receiver(), r);
530   BOOST_ASIO_CHECK(call_count == 1);
531 
532   call_count = 0;
533   non_const_member_submit s5;
534   exec::submit(s5, r);
535   BOOST_ASIO_CHECK(call_count == 1);
536 
537   call_count = 0;
538   free_submit_non_const_receiver s6;
539   exec::submit(s6, r);
540   BOOST_ASIO_CHECK(call_count == 1);
541 
542   call_count = 0;
543   executor s7;
544   exec::submit(s7, r);
545   BOOST_ASIO_CHECK(call_count == 1);
546 
547   call_count = 0;
548   const executor s8;
549   exec::submit(s8, r);
550   BOOST_ASIO_CHECK(call_count == 1);
551 
552   call_count = 0;
553   exec::submit(executor(), r);
554   BOOST_ASIO_CHECK(call_count == 1);
555 }
556 
557 BOOST_ASIO_TEST_SUITE
558 (
559   "submit",
560   BOOST_ASIO_TEST_CASE(test_can_submit)
561   BOOST_ASIO_TEST_CASE(test_submit)
562 )
563