21template <
typename T =
void,
typename Allocator = HeapFrameAllocator>
32 [[nodiscard]]
static void*
operator new(std::size_t size) {
33 return Allocator::allocate(size);
36 static void operator delete(
void* ptr)
noexcept {
37 Allocator::deallocate(ptr, 0);
40 static void operator delete(
void* ptr, std::size_t size)
noexcept {
41 Allocator::deallocate(ptr, size);
45 return Task(std::coroutine_handle<promise_type>::from_promise(*
this));
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;
57 return std::noop_coroutine();
59 void await_resume()
noexcept {}
61 return FinalAwaiter{};
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);
71#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
77 constexpr Task() noexcept = default;
93 : _handle(std::exchange(other._handle,
nullptr))
101 _handle = std::exchange(other._handle,
nullptr);
107 [[nodiscard]]
bool done() const noexcept {
108 return !_handle || _handle.done();
113 if (_handle && !_handle.done()) {
120 return !_handle || _handle.done();
123 std::coroutine_handle<>
await_suspend(std::coroutine_handle<> awaiting)
noexcept {
124 _handle.promise().continuation = awaiting;
129#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
130 if (_handle.promise().exception) {
131 std::rethrow_exception(_handle.promise().exception);
134 return std::move(_handle.promise().value);
138 [[nodiscard]] std::coroutine_handle<promise_type>
handle() const noexcept {
143 std::coroutine_handle<promise_type> _handle{
nullptr};
147template <
typename Allocator>
153 struct promise_type {
157 [[nodiscard]]
static void*
operator new(std::size_t size) {
158 return Allocator::allocate(size);
161 static void operator delete(
void* ptr)
noexcept {
162 Allocator::deallocate(ptr, 0);
165 static void operator delete(
void* ptr, std::size_t size)
noexcept {
166 Allocator::deallocate(ptr, size);
170 return Task(std::coroutine_handle<promise_type>::from_promise(*
this));
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;
182 return std::noop_coroutine();
184 void await_resume()
noexcept {}
186 return FinalAwaiter{};
192#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
198 constexpr Task() noexcept = default;
200 explicit
Task(std::coroutine_handle<promise_type>
handle) noexcept
214 : _handle(std::exchange(other._handle,
nullptr))
218 if (
this != &other) {
222 _handle = std::exchange(other._handle,
nullptr);
227 [[nodiscard]]
bool done() const noexcept {
228 return !_handle || _handle.done();
232 if (_handle && !_handle.done()) {
238 return !_handle || _handle.done();
241 std::coroutine_handle<>
await_suspend(std::coroutine_handle<> awaiting)
noexcept {
242 _handle.promise().continuation = awaiting;
247#if defined(__cpp_exceptions) || defined(__EXCEPTIONS)
248 if (_handle.promise().exception) {
249 std::rethrow_exception(_handle.promise().exception);
254 [[nodiscard]] std::coroutine_handle<promise_type>
handle() const noexcept {
259 std::coroutine_handle<promise_type> _handle{
nullptr};
263template <
typename T =
void, std::
size_t MaxFrames = 16, std::
size_t FrameSize = 256>
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
Task(const Task &)=delete
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
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