Commit 1e4aa258 authored by Xavier Thompson's avatar Xavier Thompson

WIP

parent a429ac16
...@@ -2,102 +2,29 @@ ...@@ -2,102 +2,29 @@
#define __PROMISE_HPP__ #define __PROMISE_HPP__
#include <cassert>
#include <exception>
#include <memory>
#include <type_traits> #include <type_traits>
#include <result.hpp>
namespace typon::detail
namespace typon
{ {
template <typename T> template <typename T>
struct promise struct promise
{ {
enum { Exception, Value } _tag = Exception; result<T>* _result;
union
{
T _value;
std::exception_ptr _exception = nullptr;
};
~promise()
{
switch(_tag)
{
case Value:
std::destroy_at(std::addressof(_value));
break;
case Exception:
std::destroy_at(std::addressof(_exception));
break;
}
}
template <typename U> template <typename U>
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)); _result->return_value(std::forward<U>(expr));
_tag = Value;
}
void unhandled_exception() noexcept
{
_exception = std::current_exception();
_tag = Exception;
}
T& get() &
{
switch (_tag)
{
case Value:
return _value;
case Exception:
assert(_exception)
std::rethrow_exception(_exception);
}
}
T&& get() &&
{
switch (_tag)
{
case Value:
return std::move(_value);
case Exception:
std::rethrow_exception(_exception);
}
}
};
template <typename T>
struct promise<T&>
{
T* _value;
std::exception_ptr _exception;
void return_value(T& expr) noexcept
{
_value = std::addressof(expr);
} }
void unhandled_exception() noexcept void unhandled_exception() noexcept
{ {
_exception = std::current_exception(); _result->unhandled_exception();
}
T& get() &
{
if (_exception)
{
std::rethrow_exception(_exception);
}
return *_value;
} }
}; };
...@@ -107,21 +34,13 @@ namespace typon::detail ...@@ -107,21 +34,13 @@ namespace typon::detail
struct promise<void> struct promise<void>
{ {
std::exception_ptr _exception; result<void>* _result;
void return_void() noexcept {} void return_void() noexcept {}
void unhandled_exception() noexcept void unhandled_exception() noexcept
{ {
_exception = std::current_exception(); _result->unhandled_exception();
}
void get()
{
if (_exception)
{
std::rethrow_exception(_exception);
}
} }
}; };
......
#ifndef __RESULT_HPP__
#define __RESULT_HPP__
#include <exception>
#include <memory>
#include <type_traits>
namespace typon
{
template <typename T>
struct result
{
std::exception_ptr _exception;
union
{
T _value;
};
~result()
{
if (!_exception)
{
std::destroy_at(std::addressof(_value));
}
}
template <typename U>
void return_value(U&& expr) noexcept(std::is_nothrow_constructible_v<T, U&&>)
{
std::construct_at(std::addressof(_value), std::forward<U>(expr));
}
void unhandled_exception() noexcept
{
_exception = std::current_exception();
}
T& get() &
{
if (_exception)
{
std::rethrow_exception(_exception);
}
return _value;
}
T&& get() &&
{
if (_exception)
{
std::rethrow_exception(_exception);
}
return std::move(_value);
}
};
template <typename T>
struct result<T&>
{
T* _value;
std::exception_ptr _exception;
void return_value(T& expr) noexcept
{
_value = std::addressof(expr);
}
void unhandled_exception() noexcept
{
_exception = std::current_exception();
}
T& get() &
{
if (_exception)
{
std::rethrow_exception(_exception);
}
return *_value;
}
};
template <>
struct result<void>
{
std::exception_ptr _exception;
void unhandled_exception() noexcept
{
_exception = std::current_exception();
}
void get()
{
if (_exception)
{
std::rethrow_exception(_exception);
}
}
};
}
#endif // __RESULT_HPP__
...@@ -4,23 +4,31 @@ ...@@ -4,23 +4,31 @@
#include <coroutine> #include <coroutine>
#include <promise.hpp> #include <promise.hpp>
#include <result.hpp>
namespace typon namespace typon
{ {
template <typename T = void> template <typename T = void>
struct [[nodiscard]] task //struct [[nodiscard]] task
struct task
{ {
struct promise_type;
std::coroutine_handle<promise_type> _coroutine;
result<T> _result;
template <typename T>
struct promise_type : promise<T> struct promise_type : promise<T>
{ {
std::coroutine_handle _continuation; // std::coroutine_handle<> _continuation;
task get_return_object() noexcept task get_return_object() noexcept
{ {
return task { std::coroutine_handle<promise<T>>::from_promise(*this) }; task _task { std::coroutine_handle<promise_type>::from_promise(*this), result<T> {} };
this->_result = std::addressof(_task._result);
return _task;
} }
std::suspend_never initial_suspend() noexcept std::suspend_never initial_suspend() noexcept
...@@ -28,26 +36,23 @@ namespace typon ...@@ -28,26 +36,23 @@ namespace typon
return {}; return {};
} }
auto final_suspend() noexcept std::suspend_never final_suspend() noexcept
{
struct awaitable : std::suspend_always
{ {
template <typename Promise> return {};
void await_suspend(std::coroutine_handle<Promise> coroutine) noexcept
{
return coroutine.promise()._continuation;
}
void await_resume() noexcept { /*unreachable*/ };
}
return awaitable {};
} }
}; };
auto operator co_await() const&& noexcept // auto operator co_await() const&& noexcept
{ // {
struct awaitable : std::suspend_always // struct awaitable
} // {
// bool await_ready() noexcept
// {
// }
// };
// }
}; };
......
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