• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // connect.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/connect.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_connect_1
54 {
55 };
56 
57 struct no_connect_2 : exec::sender_base
58 {
59 };
60 
61 struct no_connect_3
62 {
63   template <typename R>
connectno_connect_364   operation_state connect(BOOST_ASIO_MOVE_ARG(R) r)
65   {
66     (void)r;
67     return operation_state();
68   }
69 };
70 
71 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
72 
73 namespace boost {
74 namespace asio {
75 namespace traits {
76 
77 template <typename R>
78 struct connect_member<no_connect_3, R>
79 {
80   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
81   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
82   typedef operation_state result_type;
83 };
84 
85 } // namespace traits
86 } // namespace asio
87 } // namespace boost
88 
89 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
90 
91 struct const_member_connect : exec::sender_base
92 {
const_member_connectconst_member_connect93   const_member_connect()
94   {
95   }
96 
97   template <typename R>
connectconst_member_connect98   operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
99   {
100     (void)r;
101     ++call_count;
102     return operation_state();
103   }
104 };
105 
106 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
107 
108 namespace boost {
109 namespace asio {
110 namespace traits {
111 
112 template <typename R>
113 struct connect_member<const const_member_connect, R>
114 {
115   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
116   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
117   typedef operation_state result_type;
118 };
119 
120 } // namespace traits
121 } // namespace asio
122 } // namespace boost
123 
124 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
125 
126 struct free_connect_const_receiver : exec::sender_base
127 {
free_connect_const_receiverfree_connect_const_receiver128   free_connect_const_receiver()
129   {
130   }
131 
132   template <typename R>
connect(const free_connect_const_receiver &,BOOST_ASIO_MOVE_ARG (R)r)133   friend operation_state connect(
134       const free_connect_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
135   {
136     (void)r;
137     ++call_count;
138     return operation_state();
139   }
140 };
141 
142 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
143 
144 namespace boost {
145 namespace asio {
146 namespace traits {
147 
148 template <typename R>
149 struct connect_free<const free_connect_const_receiver, R>
150 {
151   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
152   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
153   typedef operation_state result_type;
154 };
155 
156 } // namespace traits
157 } // namespace asio
158 } // namespace boost
159 
160 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
161 
162 struct non_const_member_connect : exec::sender_base
163 {
164   template <typename R>
connectnon_const_member_connect165   operation_state connect(BOOST_ASIO_MOVE_ARG(R) r)
166   {
167     (void)r;
168     ++call_count;
169     return operation_state();
170   }
171 };
172 
173 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
174 
175 namespace boost {
176 namespace asio {
177 namespace traits {
178 
179 template <typename R>
180 struct connect_member<non_const_member_connect, R>
181 {
182   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
183   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
184   typedef operation_state result_type;
185 };
186 
187 } // namespace traits
188 } // namespace asio
189 } // namespace boost
190 
191 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
192 
193 struct free_connect_non_const_receiver : exec::sender_base
194 {
free_connect_non_const_receiverfree_connect_non_const_receiver195   free_connect_non_const_receiver()
196   {
197   }
198 
199   template <typename R>
connect(free_connect_non_const_receiver &,BOOST_ASIO_MOVE_ARG (R)r)200   friend operation_state connect(
201       free_connect_non_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
202   {
203     (void)r;
204     ++call_count;
205     return operation_state();
206   }
207 };
208 
209 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
210 
211 namespace boost {
212 namespace asio {
213 namespace traits {
214 
215 template <typename R>
216 struct connect_free<free_connect_non_const_receiver, R>
217 {
218   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
219   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
220   typedef operation_state result_type;
221 };
222 
223 } // namespace traits
224 } // namespace asio
225 } // namespace boost
226 
227 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
228 
229 struct receiver
230 {
receiverreceiver231   receiver()
232   {
233   }
234 
receiverreceiver235   receiver(const receiver&)
236   {
237   }
238 
239 #if defined(BOOST_ASIO_HAS_MOVE)
receiverreceiver240   receiver(receiver&&) BOOST_ASIO_NOEXCEPT
241   {
242   }
243 #endif // defined(BOOST_ASIO_HAS_MOVE)
244 
245   template <typename E>
set_errorreceiver246   void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
247   {
248     (void)e;
249   }
250 
set_donereceiver251   void set_done() BOOST_ASIO_NOEXCEPT
252   {
253   }
254 };
255 
256 namespace boost {
257 namespace asio {
258 namespace traits {
259 
260 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
261 
262 template <typename E>
263 struct set_error_member<receiver, E>
264 {
265   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
266   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
267   typedef void result_type;
268 };
269 
270 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
271 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
272 
273 template <>
274 struct set_done_member<receiver>
275 {
276   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
277   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
278   typedef void result_type;
279 };
280 
281 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
282 
283 } // namespace traits
284 } // namespace asio
285 } // namespace boost
286 
287 struct executor
288 {
executorexecutor289   executor()
290   {
291   }
292 
executorexecutor293   executor(const executor&) BOOST_ASIO_NOEXCEPT
294   {
295   }
296 
297 #if defined(BOOST_ASIO_HAS_MOVE)
executorexecutor298   executor(executor&&) BOOST_ASIO_NOEXCEPT
299   {
300   }
301 #endif // defined(BOOST_ASIO_HAS_MOVE)
302 
303   template <typename F>
executeexecutor304   void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
305   {
306     (void)f;
307   }
308 
operator ==executor309   bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
310   {
311     return true;
312   }
313 
operator !=executor314   bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
315   {
316     return false;
317   }
318 };
319 
320 namespace boost {
321 namespace asio {
322 namespace traits {
323 
324 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
325 
326 template <typename F>
327 struct execute_member<executor, F>
328 {
329   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
330   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
331   typedef void result_type;
332 };
333 
334 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
335 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
336 
337 template <>
338 struct equality_comparable<executor>
339 {
340   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
341   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
342 };
343 
344 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
345 
346 } // namespace traits
347 } // namespace asio
348 } // namespace boost
349 
test_can_connect()350 void test_can_connect()
351 {
352   BOOST_ASIO_CONSTEXPR bool b1 = exec::can_connect<
353       no_connect_1&, receiver>::value;
354   BOOST_ASIO_CHECK(b1 == false);
355 
356   BOOST_ASIO_CONSTEXPR bool b2 = exec::can_connect<
357       const no_connect_1&, receiver>::value;
358   BOOST_ASIO_CHECK(b2 == false);
359 
360   BOOST_ASIO_CONSTEXPR bool b3 = exec::can_connect<
361       no_connect_2&, receiver>::value;
362   BOOST_ASIO_CHECK(b3 == false);
363 
364   BOOST_ASIO_CONSTEXPR bool b4 = exec::can_connect<
365       const no_connect_2&, receiver>::value;
366   BOOST_ASIO_CHECK(b4 == false);
367 
368   BOOST_ASIO_CONSTEXPR bool b5 = exec::can_connect<
369       no_connect_3&, receiver>::value;
370   BOOST_ASIO_CHECK(b5 == false);
371 
372   BOOST_ASIO_CONSTEXPR bool b6 = exec::can_connect<
373       const no_connect_3&, receiver>::value;
374   BOOST_ASIO_CHECK(b6 == false);
375 
376   BOOST_ASIO_CONSTEXPR bool b7 = exec::can_connect<
377       const_member_connect&, receiver>::value;
378   BOOST_ASIO_CHECK(b7 == true);
379 
380   BOOST_ASIO_CONSTEXPR bool b8 = exec::can_connect<
381       const const_member_connect&, receiver>::value;
382   BOOST_ASIO_CHECK(b8 == true);
383 
384   BOOST_ASIO_CONSTEXPR bool b9 = exec::can_connect<
385       free_connect_const_receiver&, receiver>::value;
386   BOOST_ASIO_CHECK(b9 == true);
387 
388   BOOST_ASIO_CONSTEXPR bool b10 = exec::can_connect<
389       const free_connect_const_receiver&, receiver>::value;
390   BOOST_ASIO_CHECK(b10 == true);
391 
392   BOOST_ASIO_CONSTEXPR bool b11 = exec::can_connect<
393       non_const_member_connect&, receiver>::value;
394   BOOST_ASIO_CHECK(b11 == true);
395 
396   BOOST_ASIO_CONSTEXPR bool b12 = exec::can_connect<
397       const non_const_member_connect&, receiver>::value;
398   BOOST_ASIO_CHECK(b12 == false);
399 
400   BOOST_ASIO_CONSTEXPR bool b13 = exec::can_connect<
401       free_connect_non_const_receiver&, receiver>::value;
402   BOOST_ASIO_CHECK(b13 == true);
403 
404   BOOST_ASIO_CONSTEXPR bool b14 = exec::can_connect<
405       const free_connect_non_const_receiver&, receiver>::value;
406   BOOST_ASIO_CHECK(b14 == false);
407 
408   BOOST_ASIO_CONSTEXPR bool b15 = exec::can_connect<
409       executor&, receiver>::value;
410   BOOST_ASIO_CHECK(b15 == true);
411 
412   BOOST_ASIO_CONSTEXPR bool b16 = exec::can_connect<
413       const executor&, receiver>::value;
414   BOOST_ASIO_CHECK(b16 == true);
415 }
416 
increment(int * count)417 void increment(int* count)
418 {
419   ++(*count);
420 }
421 
test_connect()422 void test_connect()
423 {
424   receiver r;
425 
426   call_count = 0;
427   const_member_connect s1;
428   operation_state o1 = exec::connect(s1, r);
429   BOOST_ASIO_CHECK(call_count == 1);
430   (void)o1;
431 
432   call_count = 0;
433   const const_member_connect s2;
434   operation_state o2 = exec::connect(s2, r);
435   BOOST_ASIO_CHECK(call_count == 1);
436   (void)o2;
437 
438   call_count = 0;
439   operation_state o3 = exec::connect(const_member_connect(), r);
440   BOOST_ASIO_CHECK(call_count == 1);
441   (void)o3;
442 
443   call_count = 0;
444   free_connect_const_receiver s3;
445   operation_state o4 = exec::connect(s3, r);
446   BOOST_ASIO_CHECK(call_count == 1);
447   (void)o4;
448 
449   call_count = 0;
450   const free_connect_const_receiver s4;
451   operation_state o5 = exec::connect(s4, r);
452   BOOST_ASIO_CHECK(call_count == 1);
453   (void)o5;
454 
455   call_count = 0;
456   operation_state o6 = exec::connect(free_connect_const_receiver(), r);
457   BOOST_ASIO_CHECK(call_count == 1);
458   (void)o6;
459 
460   call_count = 0;
461   non_const_member_connect s5;
462   operation_state o7 = exec::connect(s5, r);
463   BOOST_ASIO_CHECK(call_count == 1);
464   (void)o7;
465 
466   call_count = 0;
467   free_connect_non_const_receiver s6;
468   operation_state o8 = exec::connect(s6, r);
469   BOOST_ASIO_CHECK(call_count == 1);
470   (void)o8;
471 
472   executor s7;
473   exec::connect_result<executor&,
474       receiver&>::type o9 = exec::connect(s7, r);
475   BOOST_ASIO_CHECK((
476       exec::is_operation_state<
477         exec::connect_result<executor&, receiver&>::type
478       >::value));
479   (void)o9;
480 
481   const executor s8;
482   exec::connect_result<const executor&,
483       receiver&>::type o10 = exec::connect(s8, r);
484   (void)exec::connect(s8, r);
485   BOOST_ASIO_CHECK((
486       exec::is_operation_state<
487         exec::connect_result<const executor&, receiver&>::type
488       >::value));
489   (void)o10;
490 }
491 
492 BOOST_ASIO_TEST_SUITE
493 (
494   "connect",
495   BOOST_ASIO_TEST_CASE(test_can_connect)
496   BOOST_ASIO_TEST_CASE(test_connect)
497 )
498