diff options
Diffstat (limited to '')
| -rw-r--r-- | aisa/coroutine.h | 119 |
1 files changed, 0 insertions, 119 deletions
diff --git a/aisa/coroutine.h b/aisa/coroutine.h deleted file mode 100644 index 1b55362..0000000 --- a/aisa/coroutine.h +++ /dev/null | |||
| @@ -1,119 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <coroutine> | ||
| 4 | #include <optional> | ||
| 5 | |||
| 6 | namespace aisa { | ||
| 7 | |||
| 8 | template<typename result_t> struct task_promise; | ||
| 9 | |||
| 10 | template<typename result_t> struct task : public std::coroutine_handle<task_promise<result_t>> { | ||
| 11 | using handle = std::coroutine_handle<task_promise<result_t>>; | ||
| 12 | using promise_type = task_promise<result_t>; | ||
| 13 | bool await_ready() const noexcept { return handle::done(); } | ||
| 14 | result_t await_resume() const noexcept; | ||
| 15 | template<typename other_t> void await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept; | ||
| 16 | std::optional<result_t> operator()() noexcept; | ||
| 17 | }; | ||
| 18 | |||
| 19 | template<> struct task<void> : public std::coroutine_handle<task_promise<void>> { | ||
| 20 | using handle = std::coroutine_handle<task_promise<void>>; | ||
| 21 | using promise_type = task_promise<void>; | ||
| 22 | bool await_ready() const noexcept { return handle::done(); } | ||
| 23 | void await_resume() const noexcept; | ||
| 24 | template<typename other_t> void await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept; | ||
| 25 | bool operator()() noexcept; | ||
| 26 | }; | ||
| 27 | |||
| 28 | template<typename result_t> struct task_promise { | ||
| 29 | std::coroutine_handle<> precursor; | ||
| 30 | std::optional<result_t> result; | ||
| 31 | task_promise() = default; | ||
| 32 | task_promise(const task_promise &) = delete; | ||
| 33 | task<result_t> get_return_object() noexcept { return task<result_t>{std::coroutine_handle<task_promise<result_t>>::from_promise(*this)}; } | ||
| 34 | std::suspend_never initial_suspend() const noexcept { return {}; } | ||
| 35 | std::suspend_always final_suspend() const noexcept { return {}; } | ||
| 36 | void unhandled_exception() { } | ||
| 37 | void return_value(result_t x) noexcept { result = std::move(x); } | ||
| 38 | }; | ||
| 39 | |||
| 40 | template<> struct task_promise<void> { | ||
| 41 | std::coroutine_handle<> precursor; | ||
| 42 | task_promise() = default; | ||
| 43 | task_promise(const task_promise &) = delete; | ||
| 44 | task<void> get_return_object() noexcept { return task<void>{std::coroutine_handle<task_promise<void>>::from_promise(*this)}; } | ||
| 45 | std::suspend_never initial_suspend() const noexcept { return {}; } | ||
| 46 | std::suspend_always final_suspend() const noexcept { return {}; } | ||
| 47 | void unhandled_exception() { } | ||
| 48 | void return_void() noexcept { } | ||
| 49 | }; | ||
| 50 | |||
| 51 | template<typename result_t> result_t task<result_t>::await_resume() const noexcept | ||
| 52 | { | ||
| 53 | auto x = std::move(handle::promise().result.value()); | ||
| 54 | handle::destroy(); | ||
| 55 | return x; | ||
| 56 | } | ||
| 57 | |||
| 58 | template<typename result_t> template<typename other_t> void task<result_t>::await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept | ||
| 59 | { | ||
| 60 | h.promise().precursor = *this; | ||
| 61 | } | ||
| 62 | |||
| 63 | template<typename result_t> std::optional<result_t> task<result_t>::operator()() noexcept | ||
| 64 | { | ||
| 65 | if (!handle::operator bool()) | ||
| 66 | return {}; | ||
| 67 | if (!handle::done()) { | ||
| 68 | auto &precursor = handle::promise().precursor; | ||
| 69 | if (precursor) { | ||
| 70 | if (!precursor.done()) | ||
| 71 | precursor.resume(); | ||
| 72 | if (precursor.done()) | ||
| 73 | precursor = nullptr; | ||
| 74 | } | ||
| 75 | if (!precursor) | ||
| 76 | handle::resume(); | ||
| 77 | } | ||
| 78 | if (handle::done()) { | ||
| 79 | auto x = await_resume(); | ||
| 80 | handle::operator=(nullptr); | ||
| 81 | return x; | ||
| 82 | } | ||
| 83 | return {}; | ||
| 84 | } | ||
| 85 | |||
| 86 | inline void task<void>::await_resume() const noexcept | ||
| 87 | { | ||
| 88 | handle::destroy(); | ||
| 89 | } | ||
| 90 | |||
| 91 | template<typename other_t> void task<void>::await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept | ||
| 92 | { | ||
| 93 | h.promise().precursor = *this; | ||
| 94 | } | ||
| 95 | |||
| 96 | inline bool task<void>::operator()() noexcept | ||
| 97 | { | ||
| 98 | if (!handle::operator bool()) | ||
| 99 | return true; | ||
| 100 | if (!handle::done()) { | ||
| 101 | auto &precursor = handle::promise().precursor; | ||
| 102 | if (precursor) { | ||
| 103 | if (!precursor.done()) | ||
| 104 | precursor.resume(); | ||
| 105 | if (precursor.done()) | ||
| 106 | precursor = nullptr; | ||
| 107 | } | ||
| 108 | if (!precursor) | ||
| 109 | handle::resume(); | ||
| 110 | } | ||
| 111 | if (handle::done()) { | ||
| 112 | await_resume(); | ||
| 113 | handle::operator=(nullptr); | ||
| 114 | return true; | ||
| 115 | } | ||
| 116 | return false; | ||
| 117 | } | ||
| 118 | |||
| 119 | } | ||
