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
26void 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
94void 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
167void 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
249void 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
337int package_0()
338{
339 return 42;
340}
341
342int package_ec_0(boost::system::error_code ec)
343{
344 return ec ? 0 : 42;
345}
346
347int package_ex_0(std::exception_ptr ex)
348{
349 return ex ? 0 : 42;
350}
351
352void 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
415int package_1(int i)
416{
417 return i;
418}
419
420int package_ec_1(boost::system::error_code ec, int i)
421{
422 return ec ? 0 : i;
423}
424
425int package_ex_1(std::exception_ptr ex, int i)
426{
427 return ex ? 0 : i;
428}
429
430void 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
493int package_2(int i, double)
494{
495 return i;
496}
497
498int package_ec_2(boost::system::error_code ec, int i, double)
499{
500 return ec ? 0 : i;
501}
502
503int package_ex_2(std::exception_ptr ex, int i, double)
504{
505 return ex ? 0 : i;
506}
507
508void 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
571int package_3(int i, double, char)
572{
573 return i;
574}
575
576int package_ec_3(boost::system::error_code ec, int i, double, char)
577{
578 return ec ? 0 : i;
579}
580
581int package_ex_3(std::exception_ptr ex, int i, double, char)
582{
583 return ex ? 0 : i;
584}
585
586void 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
649BOOST_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
664BOOST_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

source code of boost/libs/asio/test/use_future.cpp