mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
190 lines
5.1 KiB
Plaintext
190 lines
5.1 KiB
Plaintext
/*
|
|
This file is part of Fennix Kernel.
|
|
|
|
Fennix Kernel is free software: you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation, either version 3 of
|
|
the License, or (at your option) any later version.
|
|
|
|
Fennix Kernel is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
namespace std
|
|
{
|
|
#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
|
|
}
|