parent
94c9cd75a8
commit
d1c2352237
@ -1,106 +0,0 @@ |
|||||||
#pragma once |
|
||||||
#include <concepts> |
|
||||||
#include <coroutine> |
|
||||||
#include <exception> |
|
||||||
#include <assert.h> |
|
||||||
|
|
||||||
|
|
||||||
enum TaskStates { |
|
||||||
STARTED, AWAIT, YIELD, |
|
||||||
EXCEPTION, RETURN, |
|
||||||
RETURN_VOID, DEAD |
|
||||||
}; |
|
||||||
|
|
||||||
template<typename T> |
|
||||||
struct Task { |
|
||||||
struct promise_type; |
|
||||||
|
|
||||||
using handle_type = std::coroutine_handle<promise_type>; |
|
||||||
|
|
||||||
struct promise_type { |
|
||||||
T value_; |
|
||||||
std::exception_ptr exception_; |
|
||||||
TaskStates state_{STARTED}; |
|
||||||
|
|
||||||
Task get_return_object() { |
|
||||||
return Task(handle_type::from_promise(*this)); |
|
||||||
} |
|
||||||
|
|
||||||
std::suspend_always initial_suspend() { |
|
||||||
state_ = AWAIT; |
|
||||||
return {}; |
|
||||||
} |
|
||||||
|
|
||||||
std::suspend_always final_suspend() noexcept { |
|
||||||
return {}; |
|
||||||
} |
|
||||||
|
|
||||||
void unhandled_exception() { |
|
||||||
state_ = EXCEPTION; |
|
||||||
exception_ = std::current_exception(); |
|
||||||
} |
|
||||||
|
|
||||||
template<std::convertible_to<T> From> // C++20 concept
|
|
||||||
void return_value(From &&from) { |
|
||||||
state_ = RETURN; |
|
||||||
value_ = std::forward<From>(from); |
|
||||||
} |
|
||||||
|
|
||||||
template<std::convertible_to<T> From> // C++20 concept
|
|
||||||
std::suspend_always yield_value(From &&from) { |
|
||||||
state_ = YIELD; |
|
||||||
value_ = std::forward<From>(from); |
|
||||||
return {}; |
|
||||||
} |
|
||||||
|
|
||||||
void return_void() { |
|
||||||
state_ = RETURN_VOID; |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
handle_type h_; |
|
||||||
|
|
||||||
Task() { |
|
||||||
} |
|
||||||
|
|
||||||
Task(handle_type h) : h_(h) { |
|
||||||
} |
|
||||||
|
|
||||||
Task(const Task &t) : h_(t.h_) { |
|
||||||
} |
|
||||||
|
|
||||||
void destroy() { |
|
||||||
// this should make it safe to clal repeatedly
|
|
||||||
if(h_.promise().state_ != DEAD) { |
|
||||||
h_.destroy(); |
|
||||||
h_.promise().state_ = DEAD; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
T operator()() { |
|
||||||
assert(!h_.done()); |
|
||||||
call(); |
|
||||||
return std::move(h_.promise().value_); |
|
||||||
} |
|
||||||
|
|
||||||
bool done() { |
|
||||||
return h_.done(); |
|
||||||
} |
|
||||||
|
|
||||||
TaskStates state() { |
|
||||||
return h_.promise().state_; |
|
||||||
} |
|
||||||
|
|
||||||
private: |
|
||||||
|
|
||||||
void call() { |
|
||||||
h_(); |
|
||||||
|
|
||||||
if (h_.promise().exception_) { |
|
||||||
std::rethrow_exception(h_.promise().exception_); |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
struct Pass : std::suspend_always { |
|
||||||
}; |
|
Loading…
Reference in new issue