Corium 1.1.0
High-Performance Zero-Heap C++20 MPSC Application Runtime
Loading...
Searching...
No Matches
Task.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <coroutine>
10#include <exception>
11#include <utility>
12
14
15namespace corium::async {
16
21template <typename T = void, typename Allocator = HeapFrameAllocator>
22class Task {
23public:
24 using ValueType = T;
25 using AllocatorType = Allocator;
26
27 struct promise_type {
28 std::coroutine_handle<> continuation{nullptr};
29 T value{};
30 std::exception_ptr exception{nullptr};
31
32 [[nodiscard]] static void* operator new(std::size_t size) {
33 return Allocator::allocate(size);
34 }
35
36 static void operator delete(void* ptr) noexcept {
37 Allocator::deallocate(ptr, 0);
38 }
39
40 static void operator delete(void* ptr, std::size_t size) noexcept {
41 Allocator::deallocate(ptr, size);
42 }
43
45 return Task(std::coroutine_handle<promise_type>::from_promise(*this));
46 }
47
48 std::suspend_always initial_suspend() noexcept { return {}; }
49
50 auto final_suspend() noexcept {
51 struct FinalAwaiter {
52 bool await_ready() noexcept { return false; }
53 std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> h) noexcept {
54 if (h.promise().continuation) {
55 return h.promise().continuation;
56 }
57 return std::noop_coroutine();
58 }
59 void await_resume() noexcept {}
60 };
61 return FinalAwaiter{};
62 }
63
64 template <typename Val>
65 requires (std::is_convertible_v<Val, T>)
66 void return_value(Val&& val) noexcept(std::is_nothrow_constructible_v<T, Val>) {
67 value = std::forward<Val>(val);
68 }
69
70 void unhandled_exception() noexcept {
71#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
72 exception = std::current_exception();
73#endif
74 }
75 };
76
77 constexpr Task() noexcept = default;
78
79 explicit Task(std::coroutine_handle<promise_type> handle) noexcept
80 : _handle(handle)
81 {}
82
84 if (_handle) {
85 _handle.destroy();
86 }
87 }
88
89 Task(const Task&) = delete;
90 Task& operator=(const Task&) = delete;
91
92 Task(Task&& other) noexcept
93 : _handle(std::exchange(other._handle, nullptr))
94 {}
95
96 Task& operator=(Task&& other) noexcept {
97 if (this != &other) {
98 if (_handle) {
99 _handle.destroy();
100 }
101 _handle = std::exchange(other._handle, nullptr);
102 }
103 return *this;
104 }
105
107 [[nodiscard]] bool done() const noexcept {
108 return !_handle || _handle.done();
109 }
110
112 void resume() {
113 if (_handle && !_handle.done()) {
114 _handle.resume();
115 }
116 }
117
119 [[nodiscard]] bool await_ready() const noexcept {
120 return !_handle || _handle.done();
121 }
122
123 std::coroutine_handle<> await_suspend(std::coroutine_handle<> awaiting) noexcept {
124 _handle.promise().continuation = awaiting;
125 return _handle;
126 }
127
129#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
130 if (_handle.promise().exception) {
131 std::rethrow_exception(_handle.promise().exception);
132 }
133#endif
134 return std::move(_handle.promise().value);
135 }
136
138 [[nodiscard]] std::coroutine_handle<promise_type> handle() const noexcept {
139 return _handle;
140 }
141
142private:
143 std::coroutine_handle<promise_type> _handle{nullptr};
144};
145
147template <typename Allocator>
148class Task<void, Allocator> {
149public:
150 using ValueType = void;
151 using AllocatorType = Allocator;
152
153 struct promise_type {
154 std::coroutine_handle<> continuation{nullptr};
155 std::exception_ptr exception{nullptr};
156
157 [[nodiscard]] static void* operator new(std::size_t size) {
158 return Allocator::allocate(size);
159 }
160
161 static void operator delete(void* ptr) noexcept {
162 Allocator::deallocate(ptr, 0);
163 }
164
165 static void operator delete(void* ptr, std::size_t size) noexcept {
166 Allocator::deallocate(ptr, size);
167 }
168
170 return Task(std::coroutine_handle<promise_type>::from_promise(*this));
171 }
172
173 std::suspend_always initial_suspend() noexcept { return {}; }
174
175 auto final_suspend() noexcept {
176 struct FinalAwaiter {
177 bool await_ready() noexcept { return false; }
178 std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> h) noexcept {
179 if (h.promise().continuation) {
180 return h.promise().continuation;
181 }
182 return std::noop_coroutine();
183 }
184 void await_resume() noexcept {}
185 };
186 return FinalAwaiter{};
187 }
188
189 void return_void() noexcept {}
190
191 void unhandled_exception() noexcept {
192#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
193 exception = std::current_exception();
194#endif
195 }
196 };
197
198 constexpr Task() noexcept = default;
199
200 explicit Task(std::coroutine_handle<promise_type> handle) noexcept
201 : _handle(handle)
202 {}
203
205 if (_handle) {
206 _handle.destroy();
207 }
208 }
209
210 Task(const Task&) = delete;
211 Task& operator=(const Task&) = delete;
212
213 Task(Task&& other) noexcept
214 : _handle(std::exchange(other._handle, nullptr))
215 {}
216
217 Task& operator=(Task&& other) noexcept {
218 if (this != &other) {
219 if (_handle) {
220 _handle.destroy();
221 }
222 _handle = std::exchange(other._handle, nullptr);
223 }
224 return *this;
225 }
226
227 [[nodiscard]] bool done() const noexcept {
228 return !_handle || _handle.done();
229 }
230
231 void resume() {
232 if (_handle && !_handle.done()) {
233 _handle.resume();
234 }
235 }
236
237 [[nodiscard]] bool await_ready() const noexcept {
238 return !_handle || _handle.done();
239 }
240
241 std::coroutine_handle<> await_suspend(std::coroutine_handle<> awaiting) noexcept {
242 _handle.promise().continuation = awaiting;
243 return _handle;
244 }
245
247#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
248 if (_handle.promise().exception) {
249 std::rethrow_exception(_handle.promise().exception);
250 }
251#endif
252 }
253
254 [[nodiscard]] std::coroutine_handle<promise_type> handle() const noexcept {
255 return _handle;
256 }
257
258private:
259 std::coroutine_handle<promise_type> _handle{nullptr};
260};
261
263template <typename T = void, std::size_t MaxFrames = 16, std::size_t FrameSize = 256>
265
266} // namespace corium::async
Zero-heap static coroutine frame pool and frame allocator policies.
constexpr Task() noexcept=default
void ValueType
Definition Task.hpp:150
~Task()
Definition Task.hpp:204
Task(Task &&other) noexcept
Definition Task.hpp:213
bool await_ready() const noexcept
Definition Task.hpp:237
Allocator AllocatorType
Definition Task.hpp:151
Task & operator=(Task &&other) noexcept
Definition Task.hpp:217
std::coroutine_handle await_suspend(std::coroutine_handle<> awaiting) noexcept
Definition Task.hpp:241
bool done() const noexcept
Definition Task.hpp:227
std::coroutine_handle< promise_type > handle() const noexcept
Definition Task.hpp:254
void resume()
Definition Task.hpp:231
void await_resume()
Definition Task.hpp:246
Task & operator=(const Task &)=delete
Lightweight C++20 coroutine task with zero-heap resumption chaining and configurable frame allocator.
Definition Task.hpp:22
T ValueType
Definition Task.hpp:24
bool done() const noexcept
Check if coroutine has completed execution.
Definition Task.hpp:107
std::coroutine_handle< promise_type > handle() const noexcept
Access raw coroutine handle.
Definition Task.hpp:138
constexpr Task() noexcept=default
Allocator AllocatorType
Definition Task.hpp:25
std::coroutine_handle await_suspend(std::coroutine_handle<> awaiting) noexcept
Definition Task.hpp:123
void resume()
Resume the coroutine explicitly.
Definition Task.hpp:112
~Task()
Definition Task.hpp:83
Task & operator=(const Task &)=delete
Task(const Task &)=delete
T await_resume()
Definition Task.hpp:128
Task(Task &&other) noexcept
Definition Task.hpp:92
bool await_ready() const noexcept
Awaiter interface for co_await chaining.
Definition Task.hpp:119
Task & operator=(Task &&other) noexcept
Definition Task.hpp:96
Definition AsyncEvent.hpp:14
Definition Task.hpp:27
void unhandled_exception() noexcept
Definition Task.hpp:70
std::exception_ptr exception
Definition Task.hpp:30
auto final_suspend() noexcept
Definition Task.hpp:50
void return_value(Val &&val) noexcept(std::is_nothrow_constructible_v< T, Val >)
Definition Task.hpp:66
T value
Definition Task.hpp:29
Task get_return_object() noexcept
Definition Task.hpp:44
std::suspend_always initial_suspend() noexcept
Definition Task.hpp:48
std::coroutine_handle continuation
Definition Task.hpp:28
Task get_return_object() noexcept
Definition Task.hpp:169
void return_void() noexcept
Definition Task.hpp:189
void unhandled_exception() noexcept
Definition Task.hpp:191
std::suspend_always initial_suspend() noexcept
Definition Task.hpp:173
auto final_suspend() noexcept
Definition Task.hpp:175