#pragma once
#include <coroutine>
#include <exception>
#include <utility>
template <typename T> class Task
{
public:
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
struct promise_type
{
T value;
std::exception_ptr exception;
Task get_return_object()
{
return Task(handle_type::from_promise(*this));
}
std::suspend_never initial_suspend()
{
return {};
}
std::suspend_always final_suspend() noexcept
{
return {};
}
template <typename U> void return_value(U&& val)
{
value = std::forward<U>(val);
}
void unhandled_exception()
{
exception = std::current_exception();
}
};
Task(handle_type h) : coro(h) {}
Task(Task&& t) noexcept : coro(t.coro)
{
t.coro = nullptr;
}
~Task()
{
if(coro)
{
coro.destroy();
}
}
T get()
{
if(coro.promise().exception)
{
std::rethrow_exception(coro.promise().exception);
}
return coro.promise().value;
}
// Awaiter to allow co_await Task<T>
bool await_ready() const noexcept
{
return coro.done();
}
void await_suspend(std::coroutine_handle<> awaiting_coro)
{
// Simple synchronous execution for this placeholder
}
T await_resume()
{
return get();
}
private:
handle_type coro;
};