// // Created by selim on 03.01.2022. // #ifndef AUTOCAT_GNOME_TASK_H #define AUTOCAT_GNOME_TASK_H #include #include #include template class Task { public: struct promise_type { auto initial_suspend() const noexcept { std::cout << "initial_suspend" << std::endl; return std::suspend_never(); } auto final_suspend() const noexcept { std::cout << "final_suspend" << std::endl; return std::suspend_never(); } Task get_return_object() { std::cout << "get_return_object" << std::endl; return Task{ std::coroutine_handle::from_promise(*this) }; } void return_value(const T& value) noexcept(std::is_nothrow_copy_constructible_v) { std::cout << "return_value: " << value << std::endl; _value = value; } // void return_void() { // std::cout << "return_void" << std::endl; // } void unhandled_exception() { std::cout << "unhandled_exception" << std::endl; throw; } }; private: std::optional _value = std::nullopt; std::coroutine_handle _handle; //public: // bool await_ready() const noexcept { // std::cout << "Awaiter::await_ready" << std::endl; // return false; // } // // void await_suspend(std::coroutine_handle handle) const { // std::cout << "Awaiter::await_suspend" << std::endl; // _handle = handle; // } // // T await_resume() { // std::cout << "Awaiter::await_resume" << std::endl; // return _value.value(); // } public: void set_result(T result) { _value = result; _handle(); } }; template struct Awaiter { public: bool await_ready() const noexcept { std::cout << "Awaiter::await_ready" << std::endl; return false; } void await_suspend(std::coroutine_handle::promise_type> cont) const { std::cout << "Awaiter::await_suspend" << std::endl; } U await_resume() { std::cout << "Awaiter::await_resume" << std::endl; return _task.value(); } private: Task _task; public: explicit Awaiter(Task task): _task(task) {} }; template auto operator co_await(Task task) noexcept /*requires(!std::is_reference_v)*/ { return Awaiter(task); } #endif //AUTOCAT_GNOME_TASK_H