1 | // |
2 | // use_future.cpp |
3 | // ~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2024 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/use_future.hpp> |
18 | |
19 | #include <string> |
20 | #include "unit_test.hpp" |
21 | |
22 | #if defined(BOOST_ASIO_HAS_STD_FUTURE_CLASS) |
23 | |
24 | #include "archetypes/async_ops.hpp" |
25 | |
26 | void use_future_0_test() |
27 | { |
28 | using boost::asio::use_future; |
29 | using namespace archetypes; |
30 | |
31 | std::future<void> f; |
32 | |
33 | f = async_op_0(token: use_future); |
34 | try |
35 | { |
36 | f.get(); |
37 | } |
38 | catch (...) |
39 | { |
40 | BOOST_ASIO_CHECK(false); |
41 | } |
42 | |
43 | f = async_op_ec_0(ok: true, token: use_future); |
44 | try |
45 | { |
46 | f.get(); |
47 | } |
48 | catch (...) |
49 | { |
50 | BOOST_ASIO_CHECK(false); |
51 | } |
52 | |
53 | f = async_op_ec_0(ok: false, token: use_future); |
54 | try |
55 | { |
56 | f.get(); |
57 | BOOST_ASIO_CHECK(false); |
58 | } |
59 | catch (boost::system::system_error& e) |
60 | { |
61 | BOOST_ASIO_CHECK(e.code() == boost::asio::error::operation_aborted); |
62 | } |
63 | catch (...) |
64 | { |
65 | BOOST_ASIO_CHECK(false); |
66 | } |
67 | |
68 | f = async_op_ex_0(ok: true, token: use_future); |
69 | try |
70 | { |
71 | f.get(); |
72 | } |
73 | catch (...) |
74 | { |
75 | BOOST_ASIO_CHECK(false); |
76 | } |
77 | |
78 | f = async_op_ex_0(ok: false, token: use_future); |
79 | try |
80 | { |
81 | f.get(); |
82 | BOOST_ASIO_CHECK(false); |
83 | } |
84 | catch (std::exception& e) |
85 | { |
86 | BOOST_ASIO_CHECK(e.what() == std::string("blah" )); |
87 | } |
88 | catch (...) |
89 | { |
90 | BOOST_ASIO_CHECK(false); |
91 | } |
92 | } |
93 | |
94 | void use_future_1_test() |
95 | { |
96 | using boost::asio::use_future; |
97 | using namespace archetypes; |
98 | |
99 | std::future<int> f; |
100 | |
101 | f = async_op_1(token: use_future); |
102 | try |
103 | { |
104 | int i = f.get(); |
105 | BOOST_ASIO_CHECK(i == 42); |
106 | } |
107 | catch (...) |
108 | { |
109 | BOOST_ASIO_CHECK(false); |
110 | } |
111 | |
112 | f = async_op_ec_1(ok: true, token: use_future); |
113 | try |
114 | { |
115 | int i = f.get(); |
116 | BOOST_ASIO_CHECK(i == 42); |
117 | } |
118 | catch (...) |
119 | { |
120 | BOOST_ASIO_CHECK(false); |
121 | } |
122 | |
123 | f = async_op_ec_1(ok: false, token: use_future); |
124 | try |
125 | { |
126 | int i = f.get(); |
127 | BOOST_ASIO_CHECK(false); |
128 | (void)i; |
129 | } |
130 | catch (boost::system::system_error& e) |
131 | { |
132 | BOOST_ASIO_CHECK(e.code() == boost::asio::error::operation_aborted); |
133 | } |
134 | catch (...) |
135 | { |
136 | BOOST_ASIO_CHECK(false); |
137 | } |
138 | |
139 | f = async_op_ex_1(ok: true, token: use_future); |
140 | try |
141 | { |
142 | int i = f.get(); |
143 | BOOST_ASIO_CHECK(i == 42); |
144 | } |
145 | catch (...) |
146 | { |
147 | BOOST_ASIO_CHECK(false); |
148 | } |
149 | |
150 | f = async_op_ex_1(ok: false, token: use_future); |
151 | try |
152 | { |
153 | int i = f.get(); |
154 | BOOST_ASIO_CHECK(false); |
155 | (void)i; |
156 | } |
157 | catch (std::exception& e) |
158 | { |
159 | BOOST_ASIO_CHECK(e.what() == std::string("blah" )); |
160 | } |
161 | catch (...) |
162 | { |
163 | BOOST_ASIO_CHECK(false); |
164 | } |
165 | } |
166 | |
167 | void use_future_2_test() |
168 | { |
169 | using boost::asio::use_future; |
170 | using namespace archetypes; |
171 | |
172 | std::future<std::tuple<int, double>> f; |
173 | |
174 | f = async_op_2(token: use_future); |
175 | try |
176 | { |
177 | int i; |
178 | double d; |
179 | std::tie(args&: i, args&: d) = f.get(); |
180 | BOOST_ASIO_CHECK(i == 42); |
181 | BOOST_ASIO_CHECK(d == 2.0); |
182 | } |
183 | catch (...) |
184 | { |
185 | BOOST_ASIO_CHECK(false); |
186 | } |
187 | |
188 | f = async_op_ec_2(ok: true, token: use_future); |
189 | try |
190 | { |
191 | int i; |
192 | double d; |
193 | std::tie(args&: i, args&: d) = f.get(); |
194 | BOOST_ASIO_CHECK(i == 42); |
195 | BOOST_ASIO_CHECK(d == 2.0); |
196 | } |
197 | catch (...) |
198 | { |
199 | BOOST_ASIO_CHECK(false); |
200 | } |
201 | |
202 | f = async_op_ec_2(ok: false, token: use_future); |
203 | try |
204 | { |
205 | std::tuple<int, double> t = f.get(); |
206 | BOOST_ASIO_CHECK(false); |
207 | (void)t; |
208 | } |
209 | catch (boost::system::system_error& e) |
210 | { |
211 | BOOST_ASIO_CHECK(e.code() == boost::asio::error::operation_aborted); |
212 | } |
213 | catch (...) |
214 | { |
215 | BOOST_ASIO_CHECK(false); |
216 | } |
217 | |
218 | f = async_op_ex_2(ok: true, token: use_future); |
219 | try |
220 | { |
221 | int i; |
222 | double d; |
223 | std::tie(args&: i, args&: d) = f.get(); |
224 | BOOST_ASIO_CHECK(i == 42); |
225 | BOOST_ASIO_CHECK(d == 2.0); |
226 | } |
227 | catch (...) |
228 | { |
229 | BOOST_ASIO_CHECK(false); |
230 | } |
231 | |
232 | f = async_op_ex_2(ok: false, token: use_future); |
233 | try |
234 | { |
235 | std::tuple<int, double> t = f.get(); |
236 | BOOST_ASIO_CHECK(false); |
237 | (void)t; |
238 | } |
239 | catch (std::exception& e) |
240 | { |
241 | BOOST_ASIO_CHECK(e.what() == std::string("blah" )); |
242 | } |
243 | catch (...) |
244 | { |
245 | BOOST_ASIO_CHECK(false); |
246 | } |
247 | } |
248 | |
249 | void use_future_3_test() |
250 | { |
251 | using boost::asio::use_future; |
252 | using namespace archetypes; |
253 | |
254 | std::future<std::tuple<int, double, char>> f; |
255 | |
256 | f = async_op_3(token: use_future); |
257 | try |
258 | { |
259 | int i; |
260 | double d; |
261 | char c; |
262 | std::tie(args&: i, args&: d, args&: c) = f.get(); |
263 | BOOST_ASIO_CHECK(i == 42); |
264 | BOOST_ASIO_CHECK(d == 2.0); |
265 | BOOST_ASIO_CHECK(c == 'a'); |
266 | } |
267 | catch (...) |
268 | { |
269 | BOOST_ASIO_CHECK(false); |
270 | } |
271 | |
272 | f = async_op_ec_3(ok: true, token: use_future); |
273 | try |
274 | { |
275 | int i; |
276 | double d; |
277 | char c; |
278 | std::tie(args&: i, args&: d, args&: c) = f.get(); |
279 | BOOST_ASIO_CHECK(i == 42); |
280 | BOOST_ASIO_CHECK(d == 2.0); |
281 | BOOST_ASIO_CHECK(c == 'a'); |
282 | } |
283 | catch (...) |
284 | { |
285 | BOOST_ASIO_CHECK(false); |
286 | } |
287 | |
288 | f = async_op_ec_3(ok: false, token: use_future); |
289 | try |
290 | { |
291 | std::tuple<int, double, char> t = f.get(); |
292 | BOOST_ASIO_CHECK(false); |
293 | (void)t; |
294 | } |
295 | catch (boost::system::system_error& e) |
296 | { |
297 | BOOST_ASIO_CHECK(e.code() == boost::asio::error::operation_aborted); |
298 | } |
299 | catch (...) |
300 | { |
301 | BOOST_ASIO_CHECK(false); |
302 | } |
303 | |
304 | f = async_op_ex_3(ok: true, token: use_future); |
305 | try |
306 | { |
307 | int i; |
308 | double d; |
309 | char c; |
310 | std::tie(args&: i, args&: d, args&: c) = f.get(); |
311 | BOOST_ASIO_CHECK(i == 42); |
312 | BOOST_ASIO_CHECK(d == 2.0); |
313 | BOOST_ASIO_CHECK(c == 'a'); |
314 | } |
315 | catch (...) |
316 | { |
317 | BOOST_ASIO_CHECK(false); |
318 | } |
319 | |
320 | f = async_op_ex_3(ok: false, token: use_future); |
321 | try |
322 | { |
323 | std::tuple<int, double, char> t = f.get(); |
324 | BOOST_ASIO_CHECK(false); |
325 | (void)t; |
326 | } |
327 | catch (std::exception& e) |
328 | { |
329 | BOOST_ASIO_CHECK(e.what() == std::string("blah" )); |
330 | } |
331 | catch (...) |
332 | { |
333 | BOOST_ASIO_CHECK(false); |
334 | } |
335 | } |
336 | |
337 | int package_0() |
338 | { |
339 | return 42; |
340 | } |
341 | |
342 | int package_ec_0(boost::system::error_code ec) |
343 | { |
344 | return ec ? 0 : 42; |
345 | } |
346 | |
347 | int package_ex_0(std::exception_ptr ex) |
348 | { |
349 | return ex ? 0 : 42; |
350 | } |
351 | |
352 | void use_future_package_0_test() |
353 | { |
354 | using boost::asio::use_future; |
355 | using namespace archetypes; |
356 | |
357 | std::future<int> f; |
358 | |
359 | f = async_op_0(token: use_future(package_0)); |
360 | try |
361 | { |
362 | int i = f.get(); |
363 | BOOST_ASIO_CHECK(i == 42); |
364 | } |
365 | catch (...) |
366 | { |
367 | BOOST_ASIO_CHECK(false); |
368 | } |
369 | |
370 | f = async_op_ec_0(ok: true, token: use_future(&package_ec_0)); |
371 | try |
372 | { |
373 | int i = f.get(); |
374 | BOOST_ASIO_CHECK(i == 42); |
375 | } |
376 | catch (...) |
377 | { |
378 | BOOST_ASIO_CHECK(false); |
379 | } |
380 | |
381 | f = async_op_ec_0(ok: false, token: use_future(package_ec_0)); |
382 | try |
383 | { |
384 | int i = f.get(); |
385 | BOOST_ASIO_CHECK(i == 0); |
386 | } |
387 | catch (...) |
388 | { |
389 | BOOST_ASIO_CHECK(false); |
390 | } |
391 | |
392 | f = async_op_ex_0(ok: true, token: use_future(package_ex_0)); |
393 | try |
394 | { |
395 | int i = f.get(); |
396 | BOOST_ASIO_CHECK(i == 42); |
397 | } |
398 | catch (...) |
399 | { |
400 | BOOST_ASIO_CHECK(false); |
401 | } |
402 | |
403 | f = async_op_ex_0(ok: false, token: use_future(package_ex_0)); |
404 | try |
405 | { |
406 | int i = f.get(); |
407 | BOOST_ASIO_CHECK(i == 0); |
408 | } |
409 | catch (...) |
410 | { |
411 | BOOST_ASIO_CHECK(false); |
412 | } |
413 | } |
414 | |
415 | int package_1(int i) |
416 | { |
417 | return i; |
418 | } |
419 | |
420 | int package_ec_1(boost::system::error_code ec, int i) |
421 | { |
422 | return ec ? 0 : i; |
423 | } |
424 | |
425 | int package_ex_1(std::exception_ptr ex, int i) |
426 | { |
427 | return ex ? 0 : i; |
428 | } |
429 | |
430 | void use_future_package_1_test() |
431 | { |
432 | using boost::asio::use_future; |
433 | using namespace archetypes; |
434 | |
435 | std::future<int> f; |
436 | |
437 | f = async_op_1(token: use_future(package_1)); |
438 | try |
439 | { |
440 | int i = f.get(); |
441 | BOOST_ASIO_CHECK(i == 42); |
442 | } |
443 | catch (...) |
444 | { |
445 | BOOST_ASIO_CHECK(false); |
446 | } |
447 | |
448 | f = async_op_ec_1(ok: true, token: use_future(package_ec_1)); |
449 | try |
450 | { |
451 | int i = f.get(); |
452 | BOOST_ASIO_CHECK(i == 42); |
453 | } |
454 | catch (...) |
455 | { |
456 | BOOST_ASIO_CHECK(false); |
457 | } |
458 | |
459 | f = async_op_ec_1(ok: false, token: use_future(package_ec_1)); |
460 | try |
461 | { |
462 | int i = f.get(); |
463 | BOOST_ASIO_CHECK(i == 0); |
464 | } |
465 | catch (...) |
466 | { |
467 | BOOST_ASIO_CHECK(false); |
468 | } |
469 | |
470 | f = async_op_ex_1(ok: true, token: use_future(package_ex_1)); |
471 | try |
472 | { |
473 | int i = f.get(); |
474 | BOOST_ASIO_CHECK(i == 42); |
475 | } |
476 | catch (...) |
477 | { |
478 | BOOST_ASIO_CHECK(false); |
479 | } |
480 | |
481 | f = async_op_ex_1(ok: false, token: use_future(package_ex_1)); |
482 | try |
483 | { |
484 | int i = f.get(); |
485 | BOOST_ASIO_CHECK(i == 0); |
486 | } |
487 | catch (...) |
488 | { |
489 | BOOST_ASIO_CHECK(false); |
490 | } |
491 | } |
492 | |
493 | int package_2(int i, double) |
494 | { |
495 | return i; |
496 | } |
497 | |
498 | int package_ec_2(boost::system::error_code ec, int i, double) |
499 | { |
500 | return ec ? 0 : i; |
501 | } |
502 | |
503 | int package_ex_2(std::exception_ptr ex, int i, double) |
504 | { |
505 | return ex ? 0 : i; |
506 | } |
507 | |
508 | void use_future_package_2_test() |
509 | { |
510 | using boost::asio::use_future; |
511 | using namespace archetypes; |
512 | |
513 | std::future<int> f; |
514 | |
515 | f = async_op_2(token: use_future(package_2)); |
516 | try |
517 | { |
518 | int i = f.get(); |
519 | BOOST_ASIO_CHECK(i == 42); |
520 | } |
521 | catch (...) |
522 | { |
523 | BOOST_ASIO_CHECK(false); |
524 | } |
525 | |
526 | f = async_op_ec_2(ok: true, token: use_future(package_ec_2)); |
527 | try |
528 | { |
529 | int i = f.get(); |
530 | BOOST_ASIO_CHECK(i == 42); |
531 | } |
532 | catch (...) |
533 | { |
534 | BOOST_ASIO_CHECK(false); |
535 | } |
536 | |
537 | f = async_op_ec_2(ok: false, token: use_future(package_ec_2)); |
538 | try |
539 | { |
540 | int i = f.get(); |
541 | BOOST_ASIO_CHECK(i == 0); |
542 | } |
543 | catch (...) |
544 | { |
545 | BOOST_ASIO_CHECK(false); |
546 | } |
547 | |
548 | f = async_op_ex_2(ok: true, token: use_future(package_ex_2)); |
549 | try |
550 | { |
551 | int i = f.get(); |
552 | BOOST_ASIO_CHECK(i == 42); |
553 | } |
554 | catch (...) |
555 | { |
556 | BOOST_ASIO_CHECK(false); |
557 | } |
558 | |
559 | f = async_op_ex_2(ok: false, token: use_future(package_ex_2)); |
560 | try |
561 | { |
562 | int i = f.get(); |
563 | BOOST_ASIO_CHECK(i == 0); |
564 | } |
565 | catch (...) |
566 | { |
567 | BOOST_ASIO_CHECK(false); |
568 | } |
569 | } |
570 | |
571 | int package_3(int i, double, char) |
572 | { |
573 | return i; |
574 | } |
575 | |
576 | int package_ec_3(boost::system::error_code ec, int i, double, char) |
577 | { |
578 | return ec ? 0 : i; |
579 | } |
580 | |
581 | int package_ex_3(std::exception_ptr ex, int i, double, char) |
582 | { |
583 | return ex ? 0 : i; |
584 | } |
585 | |
586 | void use_future_package_3_test() |
587 | { |
588 | using boost::asio::use_future; |
589 | using namespace archetypes; |
590 | |
591 | std::future<int> f; |
592 | |
593 | f = async_op_3(token: use_future(package_3)); |
594 | try |
595 | { |
596 | int i = f.get(); |
597 | BOOST_ASIO_CHECK(i == 42); |
598 | } |
599 | catch (...) |
600 | { |
601 | BOOST_ASIO_CHECK(false); |
602 | } |
603 | |
604 | f = async_op_ec_3(ok: true, token: use_future(package_ec_3)); |
605 | try |
606 | { |
607 | int i = f.get(); |
608 | BOOST_ASIO_CHECK(i == 42); |
609 | } |
610 | catch (...) |
611 | { |
612 | BOOST_ASIO_CHECK(false); |
613 | } |
614 | |
615 | f = async_op_ec_3(ok: false, token: use_future(package_ec_3)); |
616 | try |
617 | { |
618 | int i = f.get(); |
619 | BOOST_ASIO_CHECK(i == 0); |
620 | } |
621 | catch (...) |
622 | { |
623 | BOOST_ASIO_CHECK(false); |
624 | } |
625 | |
626 | f = async_op_ex_3(ok: true, token: use_future(package_ex_3)); |
627 | try |
628 | { |
629 | int i = f.get(); |
630 | BOOST_ASIO_CHECK(i == 42); |
631 | } |
632 | catch (...) |
633 | { |
634 | BOOST_ASIO_CHECK(false); |
635 | } |
636 | |
637 | f = async_op_ex_3(ok: false, token: use_future(package_ex_3)); |
638 | try |
639 | { |
640 | int i = f.get(); |
641 | BOOST_ASIO_CHECK(i == 0); |
642 | } |
643 | catch (...) |
644 | { |
645 | BOOST_ASIO_CHECK(false); |
646 | } |
647 | } |
648 | |
649 | BOOST_ASIO_TEST_SUITE |
650 | ( |
651 | "use_future" , |
652 | BOOST_ASIO_TEST_CASE(use_future_0_test) |
653 | BOOST_ASIO_TEST_CASE(use_future_1_test) |
654 | BOOST_ASIO_TEST_CASE(use_future_2_test) |
655 | BOOST_ASIO_TEST_CASE(use_future_3_test) |
656 | BOOST_ASIO_TEST_CASE(use_future_package_0_test) |
657 | BOOST_ASIO_TEST_CASE(use_future_package_1_test) |
658 | BOOST_ASIO_TEST_CASE(use_future_package_2_test) |
659 | BOOST_ASIO_TEST_CASE(use_future_package_3_test) |
660 | ) |
661 | |
662 | #else // defined(BOOST_ASIO_HAS_STD_FUTURE_CLASS) |
663 | |
664 | BOOST_ASIO_TEST_SUITE |
665 | ( |
666 | "use_future" , |
667 | BOOST_ASIO_TEST_CASE(null_test) |
668 | ) |
669 | |
670 | #endif // defined(BOOST_ASIO_HAS_STD_FUTURE_CLASS) |
671 | |