10 concept has_co_await_operator = requires(T v){
11 {v.operator co_await()};
33 auto *content =
static_cast<T *
>(
this);
38 auto *content =
static_cast<T *
>(
this);
43 #ifdef LIBCORO_FRAME_COMPATIBILITY_FALLBACK
48 std::coroutine_handle<promise_type> h;
51 std::suspend_always initial_suspend() noexcept {
return {};}
52 std::suspend_always final_suspend() noexcept {
return {};}
53 void unhandled_exception() {}
55 local_coro get_return_object() {
return {
56 std::coroutine_handle<promise_type>::from_promise(*
this)
59 struct yield_awaiter {
61 static constexpr
bool await_ready() noexcept {
return false;}
62 bool await_suspend(std::coroutine_handle<promise_type> h) {
63 promise_type &p = h.promise();
64 retval = p.me->_finish;
65 if (retval)
return false;
70 bool await_resume()
const {
75 yield_awaiter yield_value(std::nullptr_t) {
return {};}
79 me->_this_coro.h = {};
86 local_coro _this_coro;
89 static local_coro processing() {
90 while (!(co_yield
nullptr));
94 _this_coro = processing();
95 _this_coro.h.promise().me =
this;
99 _this_coro.h.promise().me =
nullptr;
100 _this_coro.h.destroy();
106 _this_coro.h.resume();
117 void (*_resume_fn)(std::coroutine_handle<>) = [](std::coroutine_handle<> h) {
118 static_assert(requires(T v){{v.resume()};},
"The child class must have T::resume() function");
119 auto *me =
reinterpret_cast<frame *
>(h.address());
122 void (*_destroy_fn)(std::coroutine_handle<>) = [](std::coroutine_handle<> h) {
123 static_assert(requires(T v){{v.resume()};},
"The child class must have T::destroy() function");
124 auto *me =
reinterpret_cast<frame *
>(h.address());
128 _resume_fn =
nullptr;
139 return std::coroutine_handle<>::from_address(
this);
150 template<
typename Awt>
161 template<
typename Awt>
163 if (!awt.await_ready()) {
165 using Ret = decltype(awt.await_suspend(h));
166 if constexpr(std::is_convertible_v<Ret, std::coroutine_handle<> >) {
167 auto g = awt.await_suspend(h);
168 if (g == h)
return false;
170 }
else if constexpr(std::is_convertible_v<Ret, bool>) {
171 if (!awt.await_suspend(h)) {
bool try_await(Awt &awt)
Emulates co_await (without await_resume) with no suspend when ready.
std::coroutine_handle get_handle()
Sets done flag.
void await(Awt &awt)
Emulates co_await (without await_resume)
Creates coroutine compatible memory layout, so the object acts as an coroutine.
void resume(std::coroutine_handle<> h) noexcept
Record resumption of an coroutine.