/* 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 . */ #pragma once #ifndef __cpp_impl_coroutine #error "kernel requires -fcoroutines" #endif namespace std { namespace detail { template struct coroutine_traits_base { }; template requires requires { typename R::promise_type; } struct coroutine_traits_base { using promise_type = R::promise_type; }; } template struct coroutine_traits : detail::coroutine_traits_base { }; template struct coroutine_handle; struct noop_coroutine_promise; template <> struct coroutine_handle; using noop_coroutine_handle = coroutine_handle; noop_coroutine_handle noop_coroutine() noexcept; template struct hash; template struct hash>; template <> struct coroutine_handle { 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 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(ptr); } }; struct noop_coroutine_promise { }; template <> struct coroutine_handle { 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 {} }; }