14 #if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
16 struct 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();
66 std::list<LIBCOPP_MACRO_STD_COROUTINE_NAMESPACE coroutine_handle<>> callable_promise_test_pending_awaitable::pending;
68 static copp::callable_future<int> callable_func_int_l1(
int inout) {
69 CASE_MSG_INFO() <<
"callable inner future ready int: " << inout << std::endl;
73 static 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;
80 static 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);
89 CASE_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()));
101 static 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;
110 CASE_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()));
118 static copp::callable_future<void> callable_func_void_l1() {
119 CASE_MSG_INFO() <<
"callable inner future ready void" << std::endl;
123 static 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;
130 static copp::callable_future<void> callable_func_await_void() {
132 co_await callable_func_void_l1();
133 co_await callable_func_void_l2();
138 CASE_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()));
148 static 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;
156 CASE_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();
164 static 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;
175 CASE_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()));
186 static 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);
196 static copp::callable_future<int> callable_func_killed_by_caller_l2() {
197 int result = co_await callable_func_killed_by_caller_l3();
201 static copp::callable_future<int> callable_func_killed_by_caller_l1() {
202 int result = co_await callable_func_killed_by_caller_l2();
206 CASE_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()));
222 CASE_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()));
238 static copp::callable_future<int> callable_func_some_any_all_callable_suspend(
int value) {
239 co_await callable_promise_test_pending_awaitable();
243 static 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;
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));
276 CASE_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();
292 CASE_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();
306 static 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};
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;
332 CASE_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();
348 static 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));
381 CASE_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();
395 static 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));
428 CASE_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();
CASE_TEST(callable_promise, disabled)
#define LIBCOPP_MACRO_STD_COROUTINE_NAMESPACE
constexpr span< TELEMENT > make_span(TELEMENT *ptr, typename span< TELEMENT >::size_type count)
#define CASE_EXPECT_FALSE(c)
#define CASE_EXPECT_EQ(l, r)
#define CASE_EXPECT_TRUE(c)