diff options
| author | Julian Blake Kongslie | 2022-06-25 20:56:30 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-06-25 20:56:30 -0700 |
| commit | b71f9a58a9af53b097aeca2d84413544695643ea (patch) | |
| tree | 9038c0dca5c601b5d51a84612556ca73fa0011a0 /aisa/coroutine.h | |
| parent | Move git tag generation entirely into the Makefile. (diff) | |
| download | issim-b71f9a58a9af53b097aeca2d84413544695643ea.tar.xz | |
Include what you use.
Diffstat (limited to 'aisa/coroutine.h')
| -rw-r--r-- | aisa/coroutine.h | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/aisa/coroutine.h b/aisa/coroutine.h index a456c89..333cb26 100644 --- a/aisa/coroutine.h +++ b/aisa/coroutine.h | |||
| @@ -1,46 +1,47 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include <coroutine> | 3 | #include <coroutine> |
| 4 | #include <optional> | ||
| 4 | 5 | ||
| 5 | namespace aisa { | 6 | namespace aisa { |
| 6 | 7 | ||
| 7 | template<typename result_t> struct promise; | 8 | template<typename result_t> struct task_promise; |
| 8 | 9 | ||
| 9 | template<typename result_t> struct task : public std::coroutine_handle<promise<result_t>> { | 10 | template<typename result_t> struct task : public std::coroutine_handle<task_promise<result_t>> { |
| 10 | using handle = std::coroutine_handle<struct promise<result_t>>; | 11 | using handle = std::coroutine_handle<task_promise<result_t>>; |
| 11 | using promise_type = struct promise<result_t>; | 12 | using promise_type = task_promise<result_t>; |
| 12 | bool await_ready() const noexcept { return handle::done(); } | 13 | bool await_ready() const noexcept { return handle::done(); } |
| 13 | result_t await_resume() const noexcept; | 14 | result_t await_resume() const noexcept; |
| 14 | template<typename other_t> void await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept; | 15 | template<typename other_t> void await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept; |
| 15 | std::optional<result_t> operator()() noexcept; | 16 | std::optional<result_t> operator()() noexcept; |
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | template<> struct task<void> : public std::coroutine_handle<promise<void>> { | 19 | template<> struct task<void> : public std::coroutine_handle<task_promise<void>> { |
| 19 | using handle = std::coroutine_handle<struct promise<void>>; | 20 | using handle = std::coroutine_handle<task_promise<void>>; |
| 20 | using promise_type = struct promise<void>; | 21 | using promise_type = task_promise<void>; |
| 21 | bool await_ready() const noexcept { return handle::done(); } | 22 | bool await_ready() const noexcept { return handle::done(); } |
| 22 | void await_resume() const noexcept; | 23 | void await_resume() const noexcept; |
| 23 | template<typename other_t> void await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept; | 24 | template<typename other_t> void await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept; |
| 24 | bool operator()() noexcept; | 25 | bool operator()() noexcept; |
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 27 | template<typename result_t> struct promise { | 28 | template<typename result_t> struct task_promise { |
| 28 | std::coroutine_handle<> precursor; | 29 | std::coroutine_handle<> precursor; |
| 29 | std::optional<result_t> result; | 30 | std::optional<result_t> result; |
| 30 | promise() = default; | 31 | task_promise() = default; |
| 31 | promise(const promise &) = delete; | 32 | task_promise(const task_promise &) = delete; |
| 32 | task<result_t> get_return_object() noexcept { return task<result_t>{std::coroutine_handle<promise<result_t>>::from_promise(*this)}; } | 33 | task<result_t> get_return_object() noexcept { return task<result_t>{std::coroutine_handle<task_promise<result_t>>::from_promise(*this)}; } |
| 33 | std::suspend_never initial_suspend() const noexcept { return {}; } | 34 | std::suspend_never initial_suspend() const noexcept { return {}; } |
| 34 | std::suspend_always final_suspend() const noexcept { return {}; } | 35 | std::suspend_always final_suspend() const noexcept { return {}; } |
| 35 | void unhandled_exception() { } | 36 | void unhandled_exception() { } |
| 36 | void return_value(result_t x) noexcept { result = std::move(x); } | 37 | void return_value(result_t x) noexcept { result = std::move(x); } |
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | template<> struct promise<void> { | 40 | template<> struct task_promise<void> { |
| 40 | std::coroutine_handle<> precursor; | 41 | std::coroutine_handle<> precursor; |
| 41 | promise() = default; | 42 | task_promise() = default; |
| 42 | promise(const promise &) = delete; | 43 | task_promise(const task_promise &) = delete; |
| 43 | task<void> get_return_object() noexcept { return task<void>{std::coroutine_handle<promise<void>>::from_promise(*this)}; } | 44 | task<void> get_return_object() noexcept { return task<void>{std::coroutine_handle<task_promise<void>>::from_promise(*this)}; } |
| 44 | std::suspend_never initial_suspend() const noexcept { return {}; } | 45 | std::suspend_never initial_suspend() const noexcept { return {}; } |
| 45 | std::suspend_always final_suspend() const noexcept { return {}; } | 46 | std::suspend_always final_suspend() const noexcept { return {}; } |
| 46 | void unhandled_exception() { } | 47 | void unhandled_exception() { } |
| @@ -54,7 +55,7 @@ namespace aisa { | |||
| 54 | return std::move(x); | 55 | return std::move(x); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | template<typename result_t> template<typename other_t> void task<result_t>::await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept | 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 |
| 58 | { | 59 | { |
| 59 | h.promise().precursor = *this; | 60 | h.promise().precursor = *this; |
| 60 | } | 61 | } |
| @@ -87,7 +88,7 @@ namespace aisa { | |||
| 87 | handle::destroy(); | 88 | handle::destroy(); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | template<typename other_t> void task<void>::await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept | 91 | template<typename other_t> void task<void>::await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept |
| 91 | { | 92 | { |
| 92 | h.promise().precursor = *this; | 93 | h.promise().precursor = *this; |
| 93 | } | 94 | } |
