16#if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
19struct task_future_private_data {
23using task_future_int_type = cotask::task_future<int, task_future_private_data>;
24using task_future_void_type = cotask::task_future<void, task_future_private_data>;
25using task_future_int_type_no_private_data = cotask::task_future<int, void>;
26using task_future_void_type_no_private_data = cotask::task_future<void, void>;
27using callable_future_int_type = copp::callable_future<int>;
28using callable_future_void_type = copp::callable_future<void>;
29using generator_future_int_type = copp::generator_future<int>;
30using generator_future_void_type = copp::generator_future<void>;
32std::list<generator_future_int_type::context_pointer_type> g_task_future_pending_int_contexts;
33std::list<generator_future_void_type::context_pointer_type> g_task_future_pending_void_contexts;
34size_t g_task_future_resume_generator_count = 0;
35size_t g_task_future_suspend_generator_count = 0;
37static size_t resume_pending_contexts(std::list<int> values,
int max_count = 32767) {
39 while (max_count > 0 &&
40 (!g_task_future_pending_int_contexts.empty() || !g_task_future_pending_void_contexts.empty())) {
42 if (!g_task_future_pending_int_contexts.empty()) {
43 auto ctx = *g_task_future_pending_int_contexts.begin();
44 g_task_future_pending_int_contexts.pop_front();
46 if (!values.empty()) {
47 int val = values.front();
57 if (!g_task_future_pending_void_contexts.empty()) {
58 auto ctx = *g_task_future_pending_void_contexts.begin();
59 g_task_future_pending_void_contexts.pop_front();
69static void generator_int_suspend_callback(generator_future_int_type::context_pointer_type ctx) {
70 ++g_task_future_suspend_generator_count;
71 g_task_future_pending_int_contexts.push_back(ctx);
73static void generator_int_resume_callback(
const generator_future_int_type::context_type &) {
74 ++g_task_future_resume_generator_count;
77static callable_future_int_type task_future_func_int_l1(
int inout) {
78 CASE_MSG_INFO() <<
"callable inner future ready int: " << inout << std::endl;
82static callable_future_int_type task_future_func_int_l2(
int inout) {
83 generator_future_int_type generator{generator_int_suspend_callback, generator_int_resume_callback};
84 auto gen_res =
co_await generator;
88 co_return inout + gen_res;
91static callable_future_int_type task_future_func_await_int() {
92 auto v = task_future_func_int_l1(3);
93 auto u = task_future_func_int_l2(11);
94 int x = (
co_await v +
co_await u);
98static task_future_int_type task_func_await_int() {
99 auto current_status =
co_yield task_future_void_type::yield_status();
100 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(current_status));
101 auto private_data =
co_yield task_future_int_type::yield_private_data();
102 private_data->data = 121000;
105 auto v = task_future_func_await_int();
111static callable_future_int_type task_future_func_no_wait_int() {
112 auto v = task_future_func_int_l1(7);
113 auto u = task_future_func_int_l1(19);
114 int x = (
co_await v +
co_await u);
118static task_future_int_type task_func_no_wait_int() {
119 auto current_status =
co_yield task_future_void_type::yield_status();
120 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(current_status));
121 auto private_data =
co_yield cotask::task_private_data<task_future_private_data>();
122 private_data->data = 121000;
125 auto v = task_future_func_no_wait_int();
131static void generator_void_suspend_callback(generator_future_void_type::context_pointer_type ctx) {
132 ++g_task_future_suspend_generator_count;
133 g_task_future_pending_void_contexts.push_back(ctx);
135static void generator_void_resume_callback(
const generator_future_void_type::context_type &) {
136 ++g_task_future_resume_generator_count;
139static callable_future_void_type task_future_func_void_l1() {
140 CASE_MSG_INFO() <<
"callable inner future ready void" << std::endl;
144static callable_future_void_type task_future_func_void_l2() {
145 generator_future_void_type generator{generator_void_suspend_callback, generator_void_resume_callback};
150static callable_future_void_type task_future_func_await_void() {
151 auto v = task_future_func_void_l1();
152 auto u = task_future_func_void_l2();
158static task_future_void_type task_func_await_void() {
159 auto current_status =
co_yield task_future_void_type::yield_status();
160 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(current_status));
161 auto private_data =
co_yield task_future_void_type::yield_private_data();
162 private_data->data = 123000;
165 auto v = task_future_func_await_void();
171static callable_future_void_type task_future_func_no_wait_void() {
172 auto v = task_future_func_void_l1();
173 auto u = task_future_func_void_l1();
179static task_future_void_type task_func_no_wait_void() {
180 auto current_status =
co_yield task_future_void_type::yield_status();
181 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(current_status));
182 auto private_data =
co_yield cotask::task_private_data<task_future_private_data>();
183 private_data->data = 123000;
186 auto v = task_future_func_no_wait_void();
192static task_future_void_type_no_private_data task_func_await_pick_task_id(
193 task_future_void_type_no_private_data::id_type &output) {
194 output =
co_yield task_future_void_type_no_private_data::yield_task_id();
201CASE_TEST(task_promise, task_future_void_yield_task_id) {
202 task_future_void_type_no_private_data::id_type task_id = 0;
203 task_future_void_type_no_private_data t = task_func_await_pick_task_id(task_id);
215CASE_TEST(task_promise, task_future_integer_need_resume) {
216 size_t old_resume_generator_count = g_task_future_resume_generator_count;
217 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
219 task_future_int_type t = task_func_await_int();
220 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
229 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(t.get_status()));
236 resume_pending_contexts({100});
237 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(t.get_status()));
245 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
246 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
249CASE_TEST(task_promise, task_future_void_need_resume) {
250 size_t old_resume_generator_count = g_task_future_resume_generator_count;
251 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
253 task_future_void_type t = task_func_await_void();
254 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
263 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(t.get_status()));
270 resume_pending_contexts({100});
271 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(t.get_status()));
278 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
279 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
282CASE_TEST(task_promise, task_future_integer_no_resume) {
283 size_t old_resume_generator_count = g_task_future_resume_generator_count;
284 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
286 task_future_int_type t = task_func_no_wait_int();
287 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
296 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(t.get_status()));
304 CASE_EXPECT_EQ(old_resume_generator_count, g_task_future_resume_generator_count);
305 CASE_EXPECT_EQ(old_suspend_generator_count, g_task_future_suspend_generator_count);
308CASE_TEST(task_promise, task_future_void_no_resume) {
309 size_t old_resume_generator_count = g_task_future_resume_generator_count;
310 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
312 task_future_void_type t = task_func_no_wait_void();
313 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
322 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(t.get_status()));
329 CASE_EXPECT_EQ(old_resume_generator_count, g_task_future_resume_generator_count);
330 CASE_EXPECT_EQ(old_suspend_generator_count, g_task_future_suspend_generator_count);
334static task_future_int_type task_func_await_int_generator() {
335 generator_future_int_type generator{generator_int_suspend_callback, generator_int_resume_callback};
336 auto res =
co_await generator;
340static callable_future_int_type task_future_func_await_int_task() {
341 task_future_int_type t = task_func_await_int_generator();
343 auto res =
co_await t;
347static task_future_int_type task_func_await_int_task() {
348 task_future_int_type t = task_func_await_int_generator();
350 auto res =
co_await t;
355CASE_TEST(task_promise, callable_future_await_task) {
356 size_t old_resume_generator_count = g_task_future_resume_generator_count;
357 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
359 callable_future_int_type
f = task_future_func_await_int_task();
360 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(
f.get_status()));
364 resume_pending_contexts({1000});
365 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(
f.get_status()));
369 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
370 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
373CASE_TEST(task_promise, task_future_await_task) {
374 size_t old_resume_generator_count = g_task_future_resume_generator_count;
375 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
377 task_future_int_type t = task_func_await_int_task();
378 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
386 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(t.get_status()));
393 resume_pending_contexts({2000});
394 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(t.get_status()));
402 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
403 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
407static callable_future_int_type task_func_await_callable_and_be_killed() {
408 auto u = task_future_func_int_l2(13);
413static task_future_int_type task_func_await_and_be_killed_by_caller() {
414 auto v = task_func_await_callable_and_be_killed();
419std::shared_ptr<task_future_int_type> g_task_promise_killed_by_callee;
420static task_future_int_type task_func_await_and_be_killed_by_callee(task_future_int_type::task_status_type status) {
421 g_task_promise_killed_by_callee->kill(status);
422 auto v = task_func_await_callable_and_be_killed();
430CASE_TEST(task_promise, killed_by_caller) {
431 size_t old_resume_generator_count = g_task_future_resume_generator_count;
432 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
434 task_future_int_type t = task_func_await_and_be_killed_by_caller();
435 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
443 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(t.get_status()));
451 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kKilled),
static_cast<int>(t.get_status()));
457 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kKilled), *t.get_context()->data());
459 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
460 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
462 resume_pending_contexts({100});
463 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kKilled), *t.get_context()->data());
470 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
471 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
474CASE_TEST(task_promise, killed_by_callee) {
475 size_t old_resume_generator_count = g_task_future_resume_generator_count;
476 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
478 task_future_int_type t = task_func_await_and_be_killed_by_callee(copp::promise_status::kKilled);
479 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
486 g_task_promise_killed_by_callee = std::make_shared<task_future_int_type>(t);
488 g_task_promise_killed_by_callee.reset();
490 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kKilled),
static_cast<int>(t.get_status()));
496 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kKilled), *t.get_context()->data());
498 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
499 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
501 resume_pending_contexts({100});
502 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kKilled), *t.get_context()->data());
509 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
510 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
514CASE_TEST(task_promise, cancel_by_caller) {
515 size_t old_resume_generator_count = g_task_future_resume_generator_count;
516 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
518 task_future_int_type t = task_func_await_and_be_killed_by_caller();
519 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
527 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(t.get_status()));
535 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCancle),
static_cast<int>(t.get_status()));
541 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kCancle), *t.get_context()->data());
543 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
544 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
546 resume_pending_contexts({100});
547 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kCancle), *t.get_context()->data());
554 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
555 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
559CASE_TEST(task_promise, timeout_by_caller) {
560 size_t old_resume_generator_count = g_task_future_resume_generator_count;
561 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
563 task_future_int_type t = task_func_await_and_be_killed_by_caller();
564 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
572 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(t.get_status()));
580 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kTimeout),
static_cast<int>(t.get_status()));
586 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kTimeout), *t.get_context()->data());
588 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
589 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
591 resume_pending_contexts({100});
592 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kTimeout), *t.get_context()->data());
599 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
600 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
603CASE_TEST(task_promise, timeout_by_callee) {
604 size_t old_resume_generator_count = g_task_future_resume_generator_count;
605 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
607 task_future_int_type t = task_func_await_and_be_killed_by_callee(copp::promise_status::kTimeout);
608 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(t.get_status()));
615 g_task_promise_killed_by_callee = std::make_shared<task_future_int_type>(t);
617 g_task_promise_killed_by_callee.reset();
619 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kTimeout),
static_cast<int>(t.get_status()));
625 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kTimeout), *t.get_context()->data());
627 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
628 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
630 resume_pending_contexts({100});
631 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kTimeout), *t.get_context()->data());
638 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
639 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
643static task_future_int_type task_func_await_child_task_child() {
644 auto u = task_future_func_int_l2(53);
649static task_future_int_type task_func_await_child_task_parent(task_future_int_type &out) {
650 out = task_func_await_child_task_child();
651 int x =
co_await out;
655static task_future_int_type task_func_await_empty() {
656 task_future_int_type empty;
657 int x =
co_await empty;
664CASE_TEST(task_promise, kill_parent_only) {
665 size_t old_resume_generator_count = g_task_future_resume_generator_count;
666 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
668 task_future_int_type child;
669 task_future_int_type parent = task_func_await_child_task_parent(child);
670 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(parent.get_status()));
678 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(parent.get_status()));
685 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kCreated),
static_cast<int>(child.get_status()));
686 CASE_EXPECT_EQ(old_resume_generator_count, g_task_future_resume_generator_count);
687 CASE_EXPECT_EQ(old_suspend_generator_count, g_task_future_suspend_generator_count);
689 CASE_EXPECT_EQ(old_resume_generator_count, g_task_future_resume_generator_count);
690 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
692 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(child.get_status()));
699 CASE_EXPECT_TRUE(parent.kill(task_future_int_type::task_status_type::kTimeout));
700 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kTimeout),
static_cast<int>(parent.get_status()));
706 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kTimeout), *parent.get_context()->data());
708 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(child.get_status()));
715 resume_pending_contexts({1000});
716 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kTimeout), *parent.get_context()->data());
723 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(child.get_status()));
731 CASE_EXPECT_EQ(old_resume_generator_count + 1, g_task_future_resume_generator_count);
732 CASE_EXPECT_EQ(old_suspend_generator_count + 1, g_task_future_suspend_generator_count);
736 task_future_int_type t = task_func_await_empty();
739 task_future_int_type empty;
743 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kInvalid),
static_cast<int>(empty.get_status()));
751CASE_TEST(task_promise, task_destroy_and_auto_resume) {
752 task_future_int_type parent;
754 task_future_int_type child;
755 parent = task_func_await_child_task_parent(child);
765 task_future_int_type move_child_assign = std::move(child);
773 task_future_int_type move_child_ctor{std::move(move_child_assign)};
777 task_future_int_type copy_child_assign = move_child_ctor;
778 task_future_int_type copy_child_ctor{move_child_ctor};
784 CASE_EXPECT_EQ(copy_child_assign.get_context(), copy_child_ctor.get_context());
785 CASE_EXPECT_EQ(copy_child_assign.get_context(), move_child_ctor.get_context());
787 CASE_EXPECT_EQ(copy_child_assign.get_id(), copy_child_ctor.get_id());
788 CASE_EXPECT_EQ(copy_child_assign.get_id(), move_child_ctor.get_id());
796 CASE_EXPECT_EQ(-
static_cast<int>(copp::promise_status::kKilled), *parent.get_context()->data());
798 resume_pending_contexts({});
802static task_future_int_type task_func_await_int_simple() {
803 auto u = task_future_func_int_l2(91);
808static task_future_void_type task_func_await_void_simple() {
809 auto u = task_future_func_void_l2();
814static callable_future_int_type task_func_callable_await_task_int_simple() {
815 auto u = task_func_await_int_simple();
823CASE_TEST(task_promise, forget_to_start) {
826 auto f = task_func_callable_await_task_int_simple();
829 resume_pending_contexts({});
832CASE_TEST(task_promise, callable_then_12_1_task_return_int_and_thenable_return_normal_int) {
833 auto t = task_func_await_int_simple();
834 auto f = t.then([](task_future_int_type::context_pointer_type, task_future_int_type::value_type value) {
844 resume_pending_contexts({2000});
850CASE_TEST(task_promise, callable_then_12_2_task_return_int_and_thenable_return_normal_void) {
851 auto t = task_func_await_int_simple();
852 auto f = t.then([](
const task_future_int_type::context_pointer_type &, task_future_int_type::value_type value) {
861 resume_pending_contexts({2000});
865CASE_TEST(task_promise, callable_then_12_3_task_return_int_and_thenable_return_callable_int) {
866 auto t = task_func_await_int_simple();
867 auto f = t.then([](task_future_int_type::context_pointer_type &&,
868 task_future_int_type::value_type value) -> copp::callable_future<int> {
870 CASE_MSG_INFO() <<
"thenable return callable_future<int>" << std::endl;
878 resume_pending_contexts({2000});
884CASE_TEST(task_promise, callable_then_12_4_task_return_int_and_thenable_return_callable_void) {
885 auto t = task_func_await_int_simple();
886 auto f = t.then([](
const task_future_int_type::context_pointer_type &,
887 task_future_int_type::value_type value) -> copp::callable_future<void> {
889 CASE_MSG_INFO() <<
"thenable return callable_future<void>" << std::endl;
897 resume_pending_contexts({2000});
901CASE_TEST(task_promise, callable_then_12_5_task_return_int_and_thenable_return_callable_int) {
902 auto t = task_func_await_int_simple();
903 auto f = t.then([](task_future_int_type::context_pointer_type,
904 task_future_int_type::value_type value) -> cotask::task_future<int, void> {
906 CASE_MSG_INFO() <<
"thenable return task_future<int>" << std::endl;
914 resume_pending_contexts({2000});
920CASE_TEST(task_promise, callable_then_12_6_task_return_int_and_thenable_return_callable_void) {
921 auto t = task_func_await_int_simple();
922 auto f = t.then([](task_future_int_type::context_pointer_type &&,
923 task_future_int_type::value_type value) -> cotask::task_future<void, void> {
925 CASE_MSG_INFO() <<
"thenable return task_future<void>" << std::endl;
933 resume_pending_contexts({2000});
937CASE_TEST(task_promise, callable_then_12_7_task_return_void_and_thenable_return_normal_int) {
938 auto t = task_func_await_void_simple();
939 auto f = t.then([](task_future_void_type::context_pointer_type) {
948 resume_pending_contexts({});
954CASE_TEST(task_promise, callable_then_12_8_task_return_void_and_thenable_return_normal_void) {
955 auto t = task_func_await_void_simple();
956 auto f = t.then([](
const task_future_void_type::context_pointer_type &) {
964 resume_pending_contexts({});
968CASE_TEST(task_promise, callable_then_12_9_task_return_void_and_thenable_return_callable_int) {
969 auto t = task_func_await_void_simple();
970 auto f = t.then([](task_future_void_type::context_pointer_type) -> copp::callable_future<int> {
971 CASE_MSG_INFO() <<
"thenable return callable_future<int>" << std::endl;
979 resume_pending_contexts({});
985CASE_TEST(task_promise, callable_then_12_10_task_return_void_and_thenable_return_callable_void) {
986 auto t = task_func_await_void_simple();
987 auto f = t.then([](
const task_future_void_type::context_pointer_type &) -> copp::callable_future<void> {
988 CASE_MSG_INFO() <<
"thenable return callable_future<void>" << std::endl;
996 resume_pending_contexts({});
1000CASE_TEST(task_promise, callable_then_12_11_task_return_void_and_thenable_return_callable_int) {
1001 auto t = task_func_await_void_simple();
1002 auto f = t.then([](task_future_void_type::context_pointer_type) -> cotask::task_future<int, void> {
1003 CASE_MSG_INFO() <<
"thenable return task_future<int>" << std::endl;
1011 resume_pending_contexts({});
1017CASE_TEST(task_promise, callable_then_12_12_task_return_void_and_thenable_return_callable_void) {
1018 auto t = task_func_await_void_simple();
1019 auto f = t.then([](
const task_future_void_type::context_pointer_type &) -> cotask::task_future<void, void> {
1020 CASE_MSG_INFO() <<
"thenable return task_future<void>" << std::endl;
1028 resume_pending_contexts({});
1032CASE_TEST(task_promise, then_kill_task) {
1033 auto t = task_func_await_int_simple();
1034 auto f = t.then([](task_future_int_type::context_pointer_type ctx, task_future_int_type::value_type value) {
1036 static_cast<int>(task_future_int_type::task_status_type::kTimeout));
1037 CASE_EXPECT_EQ(-
static_cast<int>(task_future_int_type::task_status_type::kTimeout), value);
1038 CASE_MSG_INFO() <<
"thenable of timeout task return int" << std::endl;
1046 t.kill(task_future_int_type::task_status_type::kTimeout);
1049 CASE_EXPECT_EQ(-
static_cast<int>(task_future_int_type::task_status_type::kTimeout),
f.get_internal_promise().data());
1051 resume_pending_contexts({});
1054CASE_TEST(task_promise, then_empty_task) {
1055 task_future_int_type t;
1056 auto f = t.then([](task_future_int_type::context_pointer_type ctx, task_future_int_type::value_type value) {
1059 CASE_MSG_INFO() <<
"thenable of empty task return int" << std::endl;
1067 resume_pending_contexts({});
1070CASE_TEST(task_promise, then_exiting_task) {
1071 auto t = task_func_await_int_simple();
1074 resume_pending_contexts({3000});
1076 auto f = t.then([](task_future_int_type::context_pointer_type ctx, task_future_int_type::value_type value) {
1078 static_cast<int>(task_future_int_type::task_status_type::kDone));
1080 CASE_MSG_INFO() <<
"thenable of exiting task return int" << std::endl;
1089CASE_TEST(task_promise, task_then_12_1_task_return_int_and_thenable_return_normal_int) {
1090 auto t = task_func_await_int_simple();
1092 [](task_future_int_type::context_pointer_type, task_future_int_type::value_type value) {
1094 CASE_MSG_INFO() <<
"first thenable return int" << std::endl;
1099 [](cotask::task_future<int, int>::context_pointer_type ctx, task_future_int_type::value_type value) {
1101 CASE_MSG_INFO() <<
"second thenable return int" << std::endl;
1102 return value + ctx->get_private_data();
1110 resume_pending_contexts({2000});
1116CASE_TEST(task_promise, task_then_12_2_task_return_int_and_thenable_return_normal_void) {
1117 auto t = task_func_await_int_simple();
1119 [](
const task_future_int_type::context_pointer_type &, task_future_int_type::value_type value) {
1121 CASE_MSG_INFO() <<
"first thenable return void" << std::endl;
1125 [](cotask::task_future<void, int>::context_pointer_type ctx) {
1127 CASE_MSG_INFO() <<
"second thenable return void" << std::endl;
1135 resume_pending_contexts({2000});
1139CASE_TEST(task_promise, task_then_12_3_task_return_int_and_thenable_return_callable_int) {
1140 auto t = task_func_await_int_simple();
1142 [](task_future_int_type::context_pointer_type &&,
1143 task_future_int_type::value_type value) -> copp::callable_future<int> {
1145 CASE_MSG_INFO() <<
"first thenable return callable_future<int>" << std::endl;
1150 [](cotask::task_future<int, int>::context_pointer_type ctx, task_future_int_type::value_type value) {
1152 CASE_MSG_INFO() <<
"second thenable return int" << std::endl;
1153 return value + ctx->get_private_data();
1161 resume_pending_contexts({2000});
1167CASE_TEST(task_promise, task_then_12_4_task_return_int_and_thenable_return_callable_void) {
1168 auto t = task_func_await_int_simple();
1170 [](
const task_future_int_type::context_pointer_type &,
1171 task_future_int_type::value_type value) -> copp::callable_future<void> {
1173 CASE_MSG_INFO() <<
"first thenable return callable_future<void>" << std::endl;
1178 [](cotask::task_future<void, int>::context_pointer_type ctx) {
1180 CASE_MSG_INFO() <<
"second thenable return void" << std::endl;
1188 resume_pending_contexts({2000});
1192CASE_TEST(task_promise, task_then_12_5_task_return_int_and_thenable_return_callable_int) {
1193 auto t = task_func_await_int_simple();
1195 [](task_future_int_type::context_pointer_type,
1196 task_future_int_type::value_type value) -> cotask::task_future<int, void> {
1198 CASE_MSG_INFO() <<
"first thenable return task_future<int>" << std::endl;
1203 [](cotask::task_future<int, int>::context_pointer_type ctx, task_future_int_type::value_type value) {
1205 CASE_MSG_INFO() <<
"second thenable return int" << std::endl;
1206 return value + ctx->get_private_data();
1214 resume_pending_contexts({2000});
1220CASE_TEST(task_promise, task_then_12_6_task_return_int_and_thenable_return_callable_void) {
1221 auto t = task_func_await_int_simple();
1223 [](task_future_int_type::context_pointer_type &&,
1224 task_future_int_type::value_type value) -> cotask::task_future<void, void> {
1226 CASE_MSG_INFO() <<
"first thenable return task_future<void>" << std::endl;
1231 [](cotask::task_future<void, int>::context_pointer_type ctx) {
1233 CASE_MSG_INFO() <<
"second thenable return void" << std::endl;
1241 resume_pending_contexts({2000});
1245CASE_TEST(task_promise, task_then_12_7_task_return_void_and_thenable_return_normal_int) {
1246 auto t = task_func_await_void_simple();
1248 [](task_future_void_type::context_pointer_type) {
1249 CASE_MSG_INFO() <<
"first thenable return int" << std::endl;
1254 [](cotask::task_future<int, int>::context_pointer_type ctx, task_future_int_type::value_type value) {
1256 CASE_MSG_INFO() <<
"second thenable return int" << std::endl;
1257 return value + ctx->get_private_data();
1265 resume_pending_contexts({});
1271CASE_TEST(task_promise, task_then_12_8_task_return_void_and_thenable_return_normal_void) {
1272 auto t = task_func_await_void_simple();
1274 [](
const task_future_void_type::context_pointer_type &) {
1275 CASE_MSG_INFO() <<
"first thenable return void" << std::endl;
1279 [](cotask::task_future<void, int>::context_pointer_type ctx) {
1281 CASE_MSG_INFO() <<
"second thenable return void" << std::endl;
1289 resume_pending_contexts({});
1293CASE_TEST(task_promise, task_then_12_9_task_return_void_and_thenable_return_callable_int) {
1294 auto t = task_func_await_void_simple();
1296 [](task_future_void_type::context_pointer_type) -> copp::callable_future<int> {
1297 CASE_MSG_INFO() <<
"first thenable return callable_future<int>" << std::endl;
1302 [](cotask::task_future<int, int>::context_pointer_type ctx, task_future_int_type::value_type value) {
1304 CASE_MSG_INFO() <<
"second thenable return int" << std::endl;
1305 return value + ctx->get_private_data();
1313 resume_pending_contexts({});
1319CASE_TEST(task_promise, task_then_12_10_task_return_void_and_thenable_return_callable_void) {
1320 auto t = task_func_await_void_simple();
1322 [](
const task_future_void_type::context_pointer_type &) -> copp::callable_future<void> {
1323 CASE_MSG_INFO() <<
"first thenable return callable_future<void>" << std::endl;
1328 [](cotask::task_future<void, int>::context_pointer_type ctx) {
1330 CASE_MSG_INFO() <<
"second thenable return void" << std::endl;
1338 resume_pending_contexts({});
1342CASE_TEST(task_promise, task_then_12_11_task_return_void_and_thenable_return_callable_int) {
1343 auto t = task_func_await_void_simple();
1345 [](task_future_void_type::context_pointer_type) -> cotask::task_future<int, void> {
1346 CASE_MSG_INFO() <<
"first thenable return task_future<int>" << std::endl;
1351 [](cotask::task_future<int, int>::context_pointer_type ctx, task_future_int_type::value_type value) {
1353 CASE_MSG_INFO() <<
"second thenable return int" << std::endl;
1354 return value + ctx->get_private_data();
1362 resume_pending_contexts({});
1368CASE_TEST(task_promise, task_then_12_12_task_return_void_and_thenable_return_callable_void) {
1369 auto t = task_func_await_void_simple();
1371 [](
const task_future_void_type::context_pointer_type &) -> cotask::task_future<void, void> {
1372 CASE_MSG_INFO() <<
"first thenable return task_future<void>" << std::endl;
1377 [](cotask::task_future<void, int>::context_pointer_type ctx) {
1379 CASE_MSG_INFO() <<
"second thenable return void" << std::endl;
1387 resume_pending_contexts({});
1392static cotask::task_future<int, void> task_func_some_any_all_callable_suspend() {
1393 auto suspend_callback = [](generator_future_int_type::context_pointer_type ctx) {
1394 ++g_task_future_suspend_generator_count;
1395 g_task_future_pending_int_contexts.push_back(ctx);
1397 auto resume_callback = [](
const generator_future_int_type::context_type &) {
1398 ++g_task_future_resume_generator_count;
1401 auto value =
co_await generator_future_int_type(suspend_callback, resume_callback);
1405static copp::callable_future<int> task_future_func_some_callable_in_container(
size_t expect_ready_count,
1406 copp::promise_status expect_status) {
1407 size_t old_resume_generator_count = g_task_future_resume_generator_count;
1408 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
1410 size_t resume_ready_count = 0;
1412 std::vector<cotask::task_future<int, void>> tasks;
1413 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1414 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1415 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1416 for (
auto &task_object : tasks) {
1417 task_object.start();
1420 copp::some_ready<cotask::task_future<int, void>>::type readys;
1421 auto some_result =
co_await copp::some(readys, 2, tasks);
1422 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(some_result));
1425 for (
auto &ready_task : readys) {
1426 if (ready_task->is_exiting()) {
1427 result += *ready_task->get_context()->data();
1428 ++resume_ready_count;
1435 some_result =
co_await copp::some(readys, 2, tasks);
1436 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(some_result));
1441 CASE_EXPECT_EQ(old_resume_generator_count + expect_ready_count, g_task_future_resume_generator_count);
1442 CASE_EXPECT_EQ(old_suspend_generator_count + 3, g_task_future_suspend_generator_count);
1449CASE_TEST(task_promise, finish_some_in_container) {
1450 auto f = task_future_func_some_callable_in_container(2, copp::promise_status::kDone);
1455 resume_pending_contexts({471}, 1);
1457 resume_pending_contexts({473}, 1);
1462 resume_pending_contexts({});
1465CASE_TEST(task_promise, kill_some_in_container) {
1466 auto f = task_future_func_some_callable_in_container(0, copp::promise_status::kKilled);
1476 resume_pending_contexts({});
1479static copp::callable_future<int> task_future_func_some_callable_in_initialize_list(
1480 size_t expect_ready_count, copp::promise_status expect_status) {
1481 size_t old_resume_generator_count = g_task_future_resume_generator_count;
1482 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
1484 size_t resume_ready_count = 0;
1486 cotask::task_future<int, void> task1 = task_func_some_any_all_callable_suspend();
1487 cotask::task_future<int, void> task2 = task_func_some_any_all_callable_suspend();
1488 cotask::task_future<int, void> task3 = task_func_some_any_all_callable_suspend();
1493 copp::some_ready<cotask::task_future<int, void>>::type readys;
1494 std::reference_wrapper<cotask::task_future<int, void>> pending[] = {task1, task2, task3};
1495 auto some_result =
co_await copp::some(readys, 2, pending);
1496 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(some_result));
1499 for (
auto &ready_task : readys) {
1500 if (ready_task->is_exiting()) {
1501 result += *ready_task->get_context()->data();
1502 ++resume_ready_count;
1506 CASE_EXPECT_EQ(old_resume_generator_count + expect_ready_count, g_task_future_resume_generator_count);
1507 CASE_EXPECT_EQ(old_suspend_generator_count + 3, g_task_future_suspend_generator_count);
1513CASE_TEST(task_promise, finish_some_in_initialize_list) {
1514 auto f = task_future_func_some_callable_in_initialize_list(2, copp::promise_status::kDone);
1519 resume_pending_contexts({471}, 1);
1521 resume_pending_contexts({473}, 1);
1526 resume_pending_contexts({});
1530static copp::callable_future<int> task_future_func_any_callable_in_container(
size_t expect_ready_count,
1531 copp::promise_status expect_status) {
1532 size_t old_resume_generator_count = g_task_future_resume_generator_count;
1533 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
1535 size_t resume_ready_count = 0;
1537 std::vector<cotask::task_future<int, void>> tasks;
1538 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1539 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1540 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1541 for (
auto &task_object : tasks) {
1542 task_object.start();
1545 copp::any_ready<cotask::task_future<int, void>>::type readys;
1546 auto any_result =
co_await copp::any(readys, tasks);
1547 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(any_result));
1550 for (
auto &ready_task : readys) {
1551 if (ready_task->is_exiting()) {
1552 result += *ready_task->get_context()->data();
1553 ++resume_ready_count;
1557 CASE_EXPECT_EQ(old_resume_generator_count + expect_ready_count, g_task_future_resume_generator_count);
1558 CASE_EXPECT_EQ(old_suspend_generator_count + 3, g_task_future_suspend_generator_count);
1562 any_result =
co_await copp::any(readys, tasks);
1563 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(any_result));
1568 CASE_EXPECT_EQ(old_resume_generator_count + expect_ready_count, g_task_future_resume_generator_count);
1569 CASE_EXPECT_EQ(old_suspend_generator_count + 3, g_task_future_suspend_generator_count);
1576CASE_TEST(task_promise, finish_any_in_container) {
1577 auto f = task_future_func_any_callable_in_container(1, copp::promise_status::kDone);
1582 resume_pending_contexts({671}, 1);
1587 resume_pending_contexts({});
1591static copp::callable_future<int> task_future_func_all_callable_in_container(
size_t expect_ready_count,
1592 copp::promise_status expect_status) {
1593 size_t old_resume_generator_count = g_task_future_resume_generator_count;
1594 size_t old_suspend_generator_count = g_task_future_suspend_generator_count;
1596 size_t resume_ready_count = 0;
1598 std::vector<cotask::task_future<int, void>> tasks;
1599 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1600 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1601 tasks.emplace_back(task_func_some_any_all_callable_suspend());
1602 for (
auto &task_object : tasks) {
1603 task_object.start();
1606 copp::all_ready<cotask::task_future<int, void>>::type readys;
1607 auto all_result =
co_await copp::all(readys, tasks);
1608 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(all_result));
1611 for (
auto &ready_task : readys) {
1612 if (ready_task->is_exiting()) {
1613 result += *ready_task->get_context()->data();
1614 ++resume_ready_count;
1618 CASE_EXPECT_EQ(old_resume_generator_count + 3, g_task_future_resume_generator_count);
1619 CASE_EXPECT_EQ(old_suspend_generator_count + 3, g_task_future_suspend_generator_count);
1623 all_result =
co_await copp::all(readys, tasks);
1624 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(all_result));
1629 CASE_EXPECT_EQ(old_resume_generator_count + expect_ready_count, g_task_future_resume_generator_count);
1630 CASE_EXPECT_EQ(old_suspend_generator_count + 3, g_task_future_suspend_generator_count);
1637CASE_TEST(task_promise, finish_all_in_container) {
1638 auto f = task_future_func_all_callable_in_container(3, copp::promise_status::kDone);
1643 resume_pending_contexts({671}, 1);
1646 resume_pending_contexts({791, 793}, 2);
1651 resume_pending_contexts({});
constexpr auto data(TCONTAINER &&container) -> decltype(container.data())
#define CASE_EXPECT_FALSE(c)
#define CASE_EXPECT_EQ(l, r)
#define CASE_EXPECT_NE(l, r)
#define CASE_TEST(test_name, case_name)
#define CASE_EXPECT_TRUE(c)