mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-11 15:29:18 +00:00
stl: Implement coroutines
This commit is contained in:
@ -17,5 +17,173 @@
|
||||
|
||||
namespace std
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
#if __cpp_impl_coroutine
|
||||
namespace detail
|
||||
{
|
||||
template <class, class...>
|
||||
struct coroutine_traits_base
|
||||
{
|
||||
};
|
||||
|
||||
template <class R, class... Args>
|
||||
requires requires { typename R::promise_type; }
|
||||
struct coroutine_traits_base<R, Args...>
|
||||
{
|
||||
using promise_type = R::promise_type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class R, class... Args>
|
||||
struct coroutine_traits : detail::coroutine_traits_base<R, Args...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Promise = void>
|
||||
struct coroutine_handle;
|
||||
|
||||
struct noop_coroutine_promise;
|
||||
template <>
|
||||
struct coroutine_handle<noop_coroutine_promise>;
|
||||
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
|
||||
noop_coroutine_handle noop_coroutine() noexcept;
|
||||
|
||||
template <class T>
|
||||
struct hash;
|
||||
template <class P>
|
||||
struct hash<coroutine_handle<P>>;
|
||||
|
||||
template <>
|
||||
struct coroutine_handle<void>
|
||||
{
|
||||
private:
|
||||
void *ptr;
|
||||
|
||||
public:
|
||||
constexpr coroutine_handle() noexcept : ptr(nullptr) {}
|
||||
constexpr coroutine_handle(nullptr_t __nul) noexcept : ptr(__nul) {}
|
||||
|
||||
coroutine_handle &operator=(nullptr_t) noexcept
|
||||
{
|
||||
ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr void *address() const noexcept { return ptr; }
|
||||
|
||||
static constexpr coroutine_handle from_address(void *addr)
|
||||
{
|
||||
coroutine_handle temp;
|
||||
temp.ptr = addr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const noexcept { return bool(ptr); }
|
||||
bool done() const { return __builtin_coro_done(ptr); }
|
||||
void operator()() const { resume(); }
|
||||
void resume() const { __builtin_coro_resume(ptr); }
|
||||
void destroy() const { __builtin_coro_destroy(ptr); }
|
||||
};
|
||||
|
||||
constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept
|
||||
{
|
||||
return x.address() == y.address();
|
||||
}
|
||||
|
||||
// constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;
|
||||
|
||||
template <class Promise>
|
||||
struct coroutine_handle
|
||||
{
|
||||
private:
|
||||
void *ptr;
|
||||
|
||||
public:
|
||||
constexpr coroutine_handle() noexcept : ptr(nullptr) {}
|
||||
constexpr coroutine_handle(nullptr_t) noexcept : ptr(nullptr) {}
|
||||
|
||||
static coroutine_handle from_promise(Promise &promise)
|
||||
{
|
||||
coroutine_handle temp;
|
||||
temp.ptr = __builtin_coro_promise((char *)&promise, __alignof(Promise), true);
|
||||
return temp;
|
||||
}
|
||||
|
||||
coroutine_handle &operator=(nullptr_t) noexcept
|
||||
{
|
||||
ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr void *address() const noexcept { return ptr; }
|
||||
|
||||
static constexpr coroutine_handle from_address(void *addr)
|
||||
{
|
||||
coroutine_handle temp;
|
||||
temp.ptr = addr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
constexpr operator coroutine_handle<>() const noexcept
|
||||
{
|
||||
return coroutine_handle<>::from_address(address());
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const noexcept { return bool(ptr); }
|
||||
bool done() const { return __builtin_coro_done(ptr); }
|
||||
void operator()() const { resume(); }
|
||||
void resume() const { __builtin_coro_resume(ptr); }
|
||||
void destroy() const { __builtin_coro_destroy(ptr); }
|
||||
Promise &promise() const { return *static_cast<Promise *>(ptr); }
|
||||
};
|
||||
|
||||
struct noop_coroutine_promise
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct coroutine_handle<noop_coroutine_promise>
|
||||
{
|
||||
private:
|
||||
static struct __chframe
|
||||
{
|
||||
static void __stub_resume() {}
|
||||
void (*__a)() = __stub_resume;
|
||||
void (*__b)() = __stub_resume;
|
||||
struct noop_coroutine_promise __c;
|
||||
} __frame;
|
||||
void *ptr = &__frame;
|
||||
|
||||
explicit coroutine_handle() noexcept = default;
|
||||
friend coroutine_handle noop_coroutine() noexcept;
|
||||
|
||||
public:
|
||||
constexpr operator coroutine_handle<>() const noexcept { return coroutine_handle<>::from_address(address()); }
|
||||
constexpr explicit operator bool() const noexcept { return true; }
|
||||
constexpr bool done() const noexcept { return false; }
|
||||
constexpr void operator()() const noexcept {}
|
||||
constexpr void resume() const noexcept {}
|
||||
constexpr void destroy() const noexcept {}
|
||||
noop_coroutine_promise &promise() const noexcept { return __frame.__c; }
|
||||
constexpr void *address() const noexcept { return ptr; }
|
||||
};
|
||||
|
||||
inline noop_coroutine_handle::__chframe noop_coroutine_handle::__frame{};
|
||||
noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); }
|
||||
|
||||
struct suspend_never
|
||||
{
|
||||
constexpr bool await_ready() const noexcept { return true; }
|
||||
constexpr void await_suspend(coroutine_handle<>) const noexcept {}
|
||||
constexpr void await_resume() const noexcept {}
|
||||
};
|
||||
|
||||
struct suspend_always
|
||||
{
|
||||
constexpr bool await_ready() const noexcept { return false; }
|
||||
constexpr void await_suspend(coroutine_handle<>) const noexcept {}
|
||||
constexpr void await_resume() const noexcept {}
|
||||
};
|
||||
#else
|
||||
#error "kernel requires -fcoroutines"
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user