summaryrefslogtreecommitdiff
path: root/aisa/coroutine.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--aisa/coroutine.h39
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
5namespace aisa { 6namespace 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 }