Commit 854d1880 authored by Xavier Thompson's avatar Xavier Thompson

WIP Revert to Lazy coroutines

parent bb84968a
#ifndef __PROMISE_HPP__
#define __PROMISE_HPP__
#include <type_traits>
#include <result.hpp>
namespace typon
{
template <typename T>
struct promise
{
result<T>* _result;
template <typename U>
void return_value(U&& expr) noexcept(std::is_nothrow_constructible_v<T, U&&>)
{
_result->return_value(std::forward<U>(expr));
}
void unhandled_exception() noexcept
{
_result->unhandled_exception();
}
};
template <>
struct promise<void>
{
result<void>* _result;
void return_void() noexcept {}
void unhandled_exception() noexcept
{
_result->unhandled_exception();
}
};
}
#endif // __PROMISE_HPP__
...@@ -18,7 +18,6 @@ namespace typon ...@@ -18,7 +18,6 @@ namespace typon
{ {
T _value; T _value;
}; };
bool _ready;
~result() ~result()
{ {
...@@ -32,18 +31,11 @@ namespace typon ...@@ -32,18 +31,11 @@ namespace typon
void return_value(U&& expr) noexcept(std::is_nothrow_constructible_v<T, U&&>) void return_value(U&& expr) noexcept(std::is_nothrow_constructible_v<T, U&&>)
{ {
std::construct_at(std::addressof(_value), std::forward<U>(expr)); std::construct_at(std::addressof(_value), std::forward<U>(expr));
_ready = true;
} }
void unhandled_exception() noexcept void unhandled_exception() noexcept
{ {
_exception = std::current_exception(); _exception = std::current_exception();
_ready = true;
}
bool ready() const noexcept
{
return _ready;
} }
T& get() & T& get() &
...@@ -71,18 +63,15 @@ namespace typon ...@@ -71,18 +63,15 @@ namespace typon
{ {
T* _value; T* _value;
std::exception_ptr _exception; std::exception_ptr _exception;
bool _ready;
void return_value(T& expr) noexcept void return_value(T& expr) noexcept
{ {
_value = std::addressof(expr); _value = std::addressof(expr);
_ready = true;
} }
void unhandled_exception() noexcept void unhandled_exception() noexcept
{ {
_exception = std::current_exception(); _exception = std::current_exception();
_ready = true;
} }
T& get() & T& get() &
...@@ -100,17 +89,12 @@ namespace typon ...@@ -100,17 +89,12 @@ namespace typon
struct result<void> struct result<void>
{ {
std::exception_ptr _exception; std::exception_ptr _exception;
bool _ready;
void return_void() noexcept void return_void() noexcept {}
{
_ready = true;
}
void unhandled_exception() noexcept void unhandled_exception() noexcept
{ {
_exception = std::current_exception(); _exception = std::current_exception();
_ready = true;
} }
void get() void get()
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include <coroutine> #include <coroutine>
#include <result.hpp> #include <result.hpp>
#include <promise.hpp>
namespace typon namespace typon
...@@ -16,64 +15,48 @@ namespace typon ...@@ -16,64 +15,48 @@ namespace typon
struct promise_type; struct promise_type;
std::coroutine_handle<promise_type> _coroutine; std::coroutine_handle<promise_type> _coroutine;
result<T> _result;
struct promise_type : promise<T> ~task()
{
_coroutine.destroy();
}
struct promise_type : result<T>
{ {
std::coroutine_handle<> _continuation; std::coroutine_handle<> _continuation;
task get_return_object() noexcept task get_return_object() noexcept
{ {
task t {}; return { std::coroutine_handle<promise_type>::from_promise(*this) };
auto h = std::coroutine_handle<promise_type>::from_promise(*this);
t._coroutine = h;
h.promise()._result = std::addressof(t._result);
return t;
} }
std::suspend_never initial_suspend() noexcept std::suspend_always initial_suspend() noexcept
{ {
return {}; return {};
} }
auto final_suspend() noexcept auto final_suspend() noexcept
{ {
struct awaitable struct awaitable : std::suspend_always
{
bool _ready;
bool await_ready() noexcept
{ {
return _ready;
}
std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> coroutine) noexcept std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> coroutine) noexcept
{ {
return coroutine.promise()._continuation; return coroutine.promise()._continuation;
} }
void await_resume() noexcept {}
}; };
return awaitable { !_continuation }; return awaitable {};
} }
}; };
auto operator co_await() && noexcept auto operator co_await() const&& noexcept
{ {
struct awaitable struct awaitable
{ {
std::coroutine_handle<promise_type> _coroutine; std::coroutine_handle<promise_type> _coroutine;
result<T> * _result;
bool _destroy;
bool await_ready() noexcept bool await_ready() noexcept
{ {
if (_result->ready())
{
return true;
}
_destroy = true;
return false; return false;
} }
...@@ -85,20 +68,18 @@ namespace typon ...@@ -85,20 +68,18 @@ namespace typon
decltype(auto) await_resume() decltype(auto) await_resume()
{ {
if (_destroy) return _coroutine.promise().get();
{
_coroutine.destroy();
}
return _result->get();
} }
}; };
return awaitable { _coroutine, std::addressof(_result), false }; return awaitable { _coroutine };
} }
decltype(auto) call() && decltype(auto) call() const&&
{ {
return _result.get(); _coroutine.promise()._continuation = std::noop_coroutine();
_coroutine.resume();
return _coroutine.promise().get();
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment