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
{
T _value;
};
bool _ready;
~result()
{
......@@ -32,18 +31,11 @@ namespace typon
void return_value(U&& expr) noexcept(std::is_nothrow_constructible_v<T, U&&>)
{
std::construct_at(std::addressof(_value), std::forward<U>(expr));
_ready = true;
}
void unhandled_exception() noexcept
{
_exception = std::current_exception();
_ready = true;
}
bool ready() const noexcept
{
return _ready;
}
T& get() &
......@@ -71,18 +63,15 @@ namespace typon
{
T* _value;
std::exception_ptr _exception;
bool _ready;
void return_value(T& expr) noexcept
{
_value = std::addressof(expr);
_ready = true;
}
void unhandled_exception() noexcept
{
_exception = std::current_exception();
_ready = true;
}
T& get() &
......@@ -100,17 +89,12 @@ namespace typon
struct result<void>
{
std::exception_ptr _exception;
bool _ready;
void return_void() noexcept
{
_ready = true;
}
void return_void() noexcept {}
void unhandled_exception() noexcept
{
_exception = std::current_exception();
_ready = true;
}
void get()
......
......@@ -4,7 +4,6 @@
#include <coroutine>
#include <result.hpp>
#include <promise.hpp>
namespace typon
......@@ -16,64 +15,48 @@ namespace typon
struct promise_type;
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;
task get_return_object() noexcept
{
task t {};
auto h = std::coroutine_handle<promise_type>::from_promise(*this);
t._coroutine = h;
h.promise()._result = std::addressof(t._result);
return t;
return { std::coroutine_handle<promise_type>::from_promise(*this) };
}
std::suspend_never initial_suspend() noexcept
std::suspend_always initial_suspend() noexcept
{
return {};
}
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
{
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
{
std::coroutine_handle<promise_type> _coroutine;
result<T> * _result;
bool _destroy;
bool await_ready() noexcept
{
if (_result->ready())
{
return true;
}
_destroy = true;
return false;
}
......@@ -85,20 +68,18 @@ namespace typon
decltype(auto) await_resume()
{
if (_destroy)
{
_coroutine.destroy();
}
return _result->get();
return _coroutine.promise().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