14#if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
16struct callable_promise_test_pending_awaitable {
17 bool await_ready() noexcept {
return false; }
19 void await_resume() noexcept { detach(); }
21# if defined(LIBCOPP_MACRO_ENABLE_CONCEPTS) && LIBCOPP_MACRO_ENABLE_CONCEPTS
22 template <copp::DerivedPromiseBaseType TPROMISE>
24 template <class TPROMISE, typename = std::enable_if_t<std::is_base_of<copp::promise_base_type, TPROMISE>::value>>
27 pending.push_back(caller);
31 void detach() noexcept {
36 for (
auto iter = pending.begin(); iter != pending.end(); ++iter) {
37 if (*iter == current) {
45 callable_promise_test_pending_awaitable() {}
46 ~callable_promise_test_pending_awaitable() {
53 static std::list<LIBCOPP_MACRO_STD_COROUTINE_NAMESPACE coroutine_handle<>> pending;
54 static void resume_all() {
55 while (!pending.empty()) {
56 pending.front().resume();
60 static void resume_some(
int max_count) {
61 while (!pending.empty() && max_count-- > 0) {
62 pending.front().resume();
66std::list<LIBCOPP_MACRO_STD_COROUTINE_NAMESPACE coroutine_handle<>> callable_promise_test_pending_awaitable::pending;
68static copp::callable_future<int> callable_func_int_l1(
int inout) {
69 CASE_MSG_INFO() <<
"callable inner future ready int: " << inout << std::endl;
73static copp::callable_future<int> callable_func_int_l2(
int inout) {
74 CASE_MSG_INFO() <<
"callable inner future async int: " << inout << std::endl;
75 co_await callable_promise_test_pending_awaitable();
76 CASE_MSG_INFO() <<
"callable inner future return int: " << inout << std::endl;
80static copp::callable_future<int> callable_func_await_int() {
81 auto v = callable_func_int_l1(3);
82 auto u = callable_func_int_l2(11);
84 int x = (
co_await v +
co_await u);
89CASE_TEST(callable_promise, callable_future_integer_need_resume) {
90 copp::callable_future<int>
f = callable_func_await_int();
91 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(
f.get_status()));
95 callable_promise_test_pending_awaitable::resume_all();
96 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(
f.get_status()));
101static copp::callable_future<int> callable_func_await_int_ready() {
102 auto v = callable_func_int_l1(33);
103 auto u = callable_func_int_l1(31);
104 CASE_MSG_INFO() <<
"callable await int no wait" << std::endl;
105 int x = (
co_await v +
co_await u);
106 CASE_MSG_INFO() <<
"callable return int no wait" << std::endl;
110CASE_TEST(callable_promise, callable_future_integer_ready) {
111 copp::callable_future<int>
f = callable_func_await_int_ready();
113 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(
f.get_status()));
118static copp::callable_future<void> callable_func_void_l1() {
119 CASE_MSG_INFO() <<
"callable inner future ready void" << std::endl;
123static copp::callable_future<void> callable_func_void_l2() {
124 CASE_MSG_INFO() <<
"callable inner future async void" << std::endl;
125 co_await callable_promise_test_pending_awaitable();
126 CASE_MSG_INFO() <<
"callable inner future return void" << std::endl;
130static copp::callable_future<void> callable_func_await_void() {
132 co_await callable_func_void_l1();
133 co_await callable_func_void_l2();
138CASE_TEST(callable_promise, callable_future_void_need_resume) {
139 copp::callable_future<void>
f = callable_func_await_void();
140 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(
f.get_status()));
143 callable_promise_test_pending_awaitable::resume_all();
144 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(
f.get_status()));
148static copp::callable_future<void> callable_func_await_void_ready() {
149 CASE_MSG_INFO() <<
"callable await void no wait" << std::endl;
150 co_await callable_func_void_l1();
151 co_await callable_func_void_l1();
152 CASE_MSG_INFO() <<
"callable return void no wait" << std::endl;
156CASE_TEST(callable_promise, callable_future_void_ready) {
157 copp::callable_future<void>
f = callable_func_await_void_ready();
158 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(
f.get_status()));
161 callable_promise_test_pending_awaitable::resume_all();
164static copp::callable_future<int> callable_func_int_await_void() {
165 CASE_MSG_INFO() <<
"callable int await void: start" << std::endl;
166 co_await callable_func_void_l1();
167 co_await callable_func_void_l2();
168 auto v = callable_func_int_l1(17);
169 auto u = callable_func_int_l2(23);
170 int x = (
co_await v +
co_await u);
171 CASE_MSG_INFO() <<
"callable int await void: return" << std::endl;
175CASE_TEST(callable_promise, callable_future_int_await_void) {
176 copp::callable_future<int>
f = callable_func_int_await_void();
177 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(
f.get_status()));
180 callable_promise_test_pending_awaitable::resume_all();
181 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kDone),
static_cast<int>(
f.get_status()));
186static copp::callable_future<int> callable_func_killed_by_caller_l3() {
187 co_await callable_promise_test_pending_awaitable();
188 auto current_status =
co_yield copp::callable_future<int>::yield_status();
193 co_return -
static_cast<int>(current_status);
196static copp::callable_future<int> callable_func_killed_by_caller_l2() {
197 int result =
co_await callable_func_killed_by_caller_l3();
201static copp::callable_future<int> callable_func_killed_by_caller_l1() {
202 int result =
co_await callable_func_killed_by_caller_l2();
206CASE_TEST(callable_promise, killed_by_caller_resume_waiting) {
207 copp::callable_future<int>
f = callable_func_killed_by_caller_l1();
208 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(
f.get_status()));
213 f.kill(copp::promise_status::kKilled,
true);
215 CASE_EXPECT_EQ(
f.get_internal_promise().data(), -
static_cast<int>(copp::promise_status::kKilled));
218 callable_promise_test_pending_awaitable::resume_all();
219 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kKilled),
static_cast<int>(
f.get_status()));
222CASE_TEST(callable_promise, killed_by_caller_drop_generator) {
223 copp::callable_future<int>
f = callable_func_killed_by_caller_l2();
224 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kRunning),
static_cast<int>(
f.get_status()));
229 f.kill(copp::promise_status::kKilled,
true);
231 CASE_EXPECT_EQ(
f.get_internal_promise().data(), -
static_cast<int>(copp::promise_status::kKilled));
234 callable_promise_test_pending_awaitable::resume_all();
235 CASE_EXPECT_EQ(
static_cast<int>(copp::promise_status::kKilled),
static_cast<int>(
f.get_status()));
238static copp::callable_future<int> callable_func_some_any_all_callable_suspend(
int value) {
239 co_await callable_promise_test_pending_awaitable();
243static copp::callable_future<int> callable_func_some_callable_in_container(
size_t expect_ready_count,
244 copp::promise_status expect_status) {
245 size_t resume_ready_count = 0;
247 std::vector<copp::callable_future<int>> callables;
248 callables.emplace_back(callable_func_some_any_all_callable_suspend(471));
249 callables.emplace_back(callable_func_some_any_all_callable_suspend(473));
250 callables.emplace_back(callable_func_some_any_all_callable_suspend(477));
252 copp::some_ready<copp::callable_future<int>>::type readys;
253 auto some_result =
co_await copp::some(readys, 2, copp::gsl::make_span(callables));
254 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(some_result));
257 for (
auto &ready_callable : readys) {
258 if (ready_callable->is_ready()) {
259 result += ready_callable->get_internal_promise().data();
260 ++resume_ready_count;
267 some_result =
co_await copp::some(readys, 2, callables);
268 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(some_result));
276CASE_TEST(callable_promise, finish_some_in_container) {
277 auto f = callable_func_some_callable_in_container(2, copp::promise_status::kDone);
282 callable_promise_test_pending_awaitable::resume_some(1);
284 callable_promise_test_pending_awaitable::resume_some(1);
289 callable_promise_test_pending_awaitable::resume_all();
292CASE_TEST(callable_promise, kill_some_in_container) {
293 auto f = callable_func_some_callable_in_container(0, copp::promise_status::kKilled);
303 callable_promise_test_pending_awaitable::resume_all();
306static copp::callable_future<int> callable_func_some_callable_in_initialize_list(
size_t expect_ready_count,
307 copp::promise_status expect_status) {
308 size_t resume_ready_count = 0;
310 copp::callable_future<int> callable1 = callable_func_some_any_all_callable_suspend(471);
311 copp::callable_future<int> callable2 = callable_func_some_any_all_callable_suspend(473);
312 copp::callable_future<int> callable3 = callable_func_some_any_all_callable_suspend(477);
314 copp::some_ready<copp::callable_future<int>>::type readys;
315 std::reference_wrapper<copp::callable_future<int>> pending[] = {callable1, callable2, callable3};
316 auto some_result =
co_await copp::some(readys, 2, copp::gsl::make_span(pending));
317 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(some_result));
320 for (
auto &ready_callable : readys) {
321 if (ready_callable->is_ready()) {
322 result += ready_callable->get_internal_promise().data();
323 ++resume_ready_count;
332CASE_TEST(callable_promise, finish_some_in_initialize_list) {
333 auto f = callable_func_some_callable_in_initialize_list(2, copp::promise_status::kDone);
338 callable_promise_test_pending_awaitable::resume_some(1);
340 callable_promise_test_pending_awaitable::resume_some(1);
345 callable_promise_test_pending_awaitable::resume_all();
348static copp::callable_future<int> callable_func_any_callable_in_container(
size_t expect_ready_count,
349 copp::promise_status expect_status) {
350 size_t resume_ready_count = 0;
352 std::vector<copp::callable_future<int>> callables;
353 callables.emplace_back(callable_func_some_any_all_callable_suspend(671));
354 callables.emplace_back(callable_func_some_any_all_callable_suspend(673));
355 callables.emplace_back(callable_func_some_any_all_callable_suspend(677));
357 copp::any_ready<copp::callable_future<int>>::type readys;
358 auto any_result =
co_await copp::any(readys, copp::gsl::make_span(&callables[0], &callables[0] + callables.size()));
359 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(any_result));
362 for (
auto &ready_callable : readys) {
363 if (ready_callable->is_ready()) {
364 result += ready_callable->get_internal_promise().data();
365 ++resume_ready_count;
372 any_result =
co_await copp::any(readys, callables);
373 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(any_result));
381CASE_TEST(callable_promise, finish_any_in_container) {
382 auto f = callable_func_any_callable_in_container(1, copp::promise_status::kDone);
387 callable_promise_test_pending_awaitable::resume_some(1);
392 callable_promise_test_pending_awaitable::resume_all();
395static copp::callable_future<int> callable_func_all_callable_in_container(
size_t expect_ready_count,
396 copp::promise_status expect_status) {
397 size_t resume_ready_count = 0;
399 std::vector<copp::callable_future<int>> callables;
400 callables.emplace_back(callable_func_some_any_all_callable_suspend(671));
401 callables.emplace_back(callable_func_some_any_all_callable_suspend(791));
402 callables.emplace_back(callable_func_some_any_all_callable_suspend(793));
404 copp::all_ready<copp::callable_future<int>>::type readys;
405 auto all_result =
co_await copp::all(readys, copp::gsl::make_span(callables.data(), callables.size()));
406 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(all_result));
409 for (
auto &ready_callable : readys) {
410 if (ready_callable->is_ready()) {
411 result += ready_callable->get_internal_promise().data();
412 ++resume_ready_count;
419 all_result =
co_await copp::all(readys, callables);
420 CASE_EXPECT_EQ(
static_cast<int>(expect_status),
static_cast<int>(all_result));
428CASE_TEST(callable_promise, finish_all_in_container) {
429 auto f = callable_func_all_callable_in_container(3, copp::promise_status::kDone);
434 callable_promise_test_pending_awaitable::resume_some(1);
437 callable_promise_test_pending_awaitable::resume_all();
442 callable_promise_test_pending_awaitable::resume_all();
#define LIBCOPP_MACRO_STD_COROUTINE_NAMESPACE
#define CASE_EXPECT_FALSE(c)
#define CASE_EXPECT_EQ(l, r)
#define CASE_TEST(test_name, case_name)
#define CASE_EXPECT_TRUE(c)