coro-unconditional-dispatch.cpp (1570B)
1 #include "coroutine_owner.hpp" 2 3 #include <coroutine> 4 #include <iostream> 5 #include <vector> 6 7 struct task 8 { 9 struct promise_type 10 { 11 ~promise_type() 12 {} 13 task get_return_object() { return {make_coroutine_owner(*this)}; } 14 std::suspend_always initial_suspend() { return {}; } 15 std::suspend_always final_suspend() noexcept { return {}; } 16 void unhandled_exception() {} 17 void return_void() {} 18 }; 19 20 task(coroutine_owner<promise_type> c) 21 : h{std::move(c)} 22 {} 23 24 bool done(void) const 25 { 26 return h->done(); 27 } 28 29 bool operator()(void) 30 { 31 h->resume(); 32 return done(); 33 } 34 35 private: 36 coroutine_owner<promise_type> h; 37 }; 38 39 bool done(task const& c) 40 { 41 return c.done(); 42 } 43 44 struct state 45 { 46 ~state() 47 { 48 std::cout << "~state()" << std::endl; 49 } 50 }; 51 52 task counter(int from, int to) 53 { 54 state s; 55 for (int i = from; i < to; ++i) 56 { 57 std::cout << "counter [" << from << ',' << to << "): " << i; 58 59 if (i >= to) 60 break; 61 std::cout << " ..." << std::endl; 62 co_await std::suspend_always{}; 63 } 64 std::cout << "DONE" << std::endl; 65 co_return; 66 } 67 68 int main() 69 { 70 std::vector<task> tasks; 71 tasks.push_back(counter(1,3)); 72 tasks.push_back(counter(4,5)); 73 tasks.push_back(counter(0,7)); 74 75 std::erase_if(tasks, done); 76 77 for (int i = 0; i < 4 and not tasks.empty(); ++i) 78 { 79 std::erase_if(tasks, [](auto& t) { return t(); }); 80 std::cout << std::endl; 81 } 82 83 if (not tasks.empty()) 84 std::cout << "Finishing early, cleaning up state of suspended tasks..." << std::endl; 85 86 return 0; 87 }