mirror of
https://github.com/tearshark/librf.git
synced 2024-10-01 15:57:07 +08:00
按照
ISO/IEC JTC1 SC22 WG21 N4860 (Date: 2020-03-31) 标准为clang实现coroutine头文件
This commit is contained in:
parent
b6328a4833
commit
11f1df9a11
@ -28,9 +28,11 @@ extern "C" void* __builtin_coro_promise(void* addr, int alignment, bool from_pro
|
||||
|
||||
extern "C" size_t __builtin_coro_size();
|
||||
extern "C" void* __builtin_coro_frame();
|
||||
extern "C" void* __builtin_coro_noop();
|
||||
extern "C" void* __builtin_coro_free(void* coro_frame);
|
||||
#pragma intrinsic(__builtin_coro_size)
|
||||
#pragma intrinsic(__builtin_coro_frame)
|
||||
#pragma intrinsic(__builtin_coro_noop)
|
||||
#pragma intrinsic(__builtin_coro_free)
|
||||
|
||||
extern "C" void* __builtin_coro_id(int align, void* promise, void* fnaddr, void* parts);
|
||||
|
@ -52,6 +52,7 @@ template <class P> struct hash<coroutine_handle<P>>;
|
||||
#include <memory> // for hash<T*>
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <compare>
|
||||
|
||||
#if defined(__clang__)
|
||||
#include "clang_builtin.h"
|
||||
@ -80,17 +81,21 @@ namespace std {
|
||||
using promise_type = typename _Tp::promise_type;
|
||||
};
|
||||
|
||||
// 17.12.2, coroutine traits
|
||||
template <typename _Ret, typename... _Args>
|
||||
struct coroutine_traits : public __coroutine_traits_sfinae<_Ret>
|
||||
{
|
||||
};
|
||||
|
||||
// 17.12.3, coroutine handle
|
||||
template <typename _Promise = void>
|
||||
class coroutine_handle;
|
||||
|
||||
template <>
|
||||
class coroutine_handle<void> {
|
||||
class coroutine_handle<void>
|
||||
{
|
||||
public:
|
||||
// 17.12.3.1, construct/reset
|
||||
constexpr coroutine_handle() noexcept : __handle_(nullptr) {}
|
||||
constexpr coroutine_handle(nullptr_t) noexcept : __handle_(nullptr) {}
|
||||
coroutine_handle& operator=(nullptr_t) noexcept {
|
||||
@ -98,28 +103,15 @@ namespace std {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 17.12.3.2, export/import
|
||||
constexpr void* address() const noexcept { return __handle_; }
|
||||
constexpr explicit operator bool() const noexcept { return __handle_; }
|
||||
|
||||
void operator()() { resume(); }
|
||||
void resume() {
|
||||
__builtin_coro_resume(__handle_);
|
||||
}
|
||||
void destroy() {
|
||||
__builtin_coro_destroy(__handle_);
|
||||
}
|
||||
bool done() const {
|
||||
return __builtin_coro_done(__handle_);
|
||||
}
|
||||
public:
|
||||
static coroutine_handle from_address(void* __addr) noexcept {
|
||||
static constexpr coroutine_handle from_address(void* __addr) noexcept {
|
||||
coroutine_handle __tmp;
|
||||
__tmp.__handle_ = __addr;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
// FIXME: Should from_address(nullptr) be allowed?
|
||||
static coroutine_handle from_address(nullptr_t) noexcept {
|
||||
static constexpr coroutine_handle from_address(nullptr_t) noexcept {
|
||||
return coroutine_handle(nullptr);
|
||||
}
|
||||
|
||||
@ -130,6 +122,22 @@ namespace std {
|
||||
"non-void pointers");
|
||||
}
|
||||
|
||||
// 17.12.3.3, observers
|
||||
constexpr explicit operator bool() const noexcept {
|
||||
return __handle_ != nullptr;
|
||||
}
|
||||
bool done() const {
|
||||
return __builtin_coro_done(__handle_);
|
||||
}
|
||||
|
||||
// 17.12.3.4, resumption
|
||||
void operator()() const { resume(); }
|
||||
void resume() const {
|
||||
__builtin_coro_resume(__handle_);
|
||||
}
|
||||
void destroy() const{
|
||||
__builtin_coro_destroy(__handle_);
|
||||
}
|
||||
private:
|
||||
bool __is_suspended() const noexcept {
|
||||
// FIXME actually implement a check for if the coro is suspended.
|
||||
@ -142,50 +150,35 @@ namespace std {
|
||||
void* __handle_;
|
||||
};
|
||||
|
||||
// 18.11.2.7 comparison operators:
|
||||
inline bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
// 17.12.3.6, comparison operators
|
||||
constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
return __x.address() == __y.address();
|
||||
}
|
||||
inline bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
return !(__x == __y);
|
||||
}
|
||||
inline bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
return less<void*>()(__x.address(), __y.address());
|
||||
}
|
||||
inline bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
return __y < __x;
|
||||
}
|
||||
inline bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
return !(__x > __y);
|
||||
}
|
||||
inline bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
return !(__x < __y);
|
||||
constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||
return __x.address() <=> __y.address();
|
||||
}
|
||||
|
||||
template <typename _Promise>
|
||||
class coroutine_handle : public coroutine_handle<> {
|
||||
class coroutine_handle : public coroutine_handle<>
|
||||
{
|
||||
using _Base = coroutine_handle<>;
|
||||
public:
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
// 18.11.2.1 construct/reset
|
||||
// 17.12.3.1, construct/reset
|
||||
using coroutine_handle<>::coroutine_handle;
|
||||
#else
|
||||
coroutine_handle() noexcept : _Base() {}
|
||||
coroutine_handle(nullptr_t) noexcept : _Base(nullptr) {}
|
||||
#endif
|
||||
|
||||
coroutine_handle& operator=(nullptr_t) noexcept {
|
||||
_Base::operator=(nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 17.12.3.5, promise access
|
||||
_Promise& promise() const {
|
||||
return *static_cast<_Promise*>(
|
||||
__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
|
||||
}
|
||||
|
||||
public:
|
||||
static coroutine_handle from_address(void* __addr) noexcept {
|
||||
// 17.12.3.2, export/import
|
||||
static constexpr coroutine_handle from_address(void* __addr) noexcept {
|
||||
coroutine_handle __tmp;
|
||||
__tmp.__handle_ = __addr;
|
||||
return __tmp;
|
||||
@ -195,7 +188,7 @@ namespace std {
|
||||
// the deleted _Promise* overload doesn't make from_address(nullptr)
|
||||
// ambiguous.
|
||||
// FIXME: should from_address work with nullptr?
|
||||
static coroutine_handle from_address(nullptr_t) noexcept {
|
||||
static constexpr coroutine_handle from_address(nullptr_t) noexcept {
|
||||
return coroutine_handle(nullptr);
|
||||
}
|
||||
|
||||
@ -223,23 +216,32 @@ namespace std {
|
||||
}
|
||||
};
|
||||
|
||||
// 17.12.4, no-op coroutines
|
||||
#if __has_builtin(__builtin_coro_noop)
|
||||
struct noop_coroutine_promise {};
|
||||
|
||||
template <>
|
||||
class coroutine_handle<noop_coroutine_promise>
|
||||
: public coroutine_handle<> {
|
||||
class coroutine_handle<noop_coroutine_promise> : public coroutine_handle<>
|
||||
{
|
||||
using _Base = coroutine_handle<>;
|
||||
using _Promise = noop_coroutine_promise;
|
||||
public:
|
||||
_Promise& promise() const {
|
||||
// 17.12.4.2.3, promise access
|
||||
_Promise& promise() const noexcept {
|
||||
return *static_cast<_Promise*>(
|
||||
__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
|
||||
}
|
||||
|
||||
// 17.12.4.2.4, address
|
||||
constexpr void* address() const noexcept {
|
||||
return this->__handle_;
|
||||
}
|
||||
|
||||
// 17.12.4.2.1, observers
|
||||
constexpr explicit operator bool() const noexcept { return true; }
|
||||
constexpr bool done() const noexcept { return false; }
|
||||
|
||||
// 17.12.4.2.2, resumption
|
||||
constexpr void operator()() const noexcept {}
|
||||
constexpr void resume() const noexcept {}
|
||||
constexpr void destroy() const noexcept {}
|
||||
@ -251,28 +253,30 @@ namespace std {
|
||||
};
|
||||
|
||||
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
|
||||
|
||||
|
||||
inline noop_coroutine_handle noop_coroutine() noexcept {
|
||||
return noop_coroutine_handle();
|
||||
}
|
||||
#endif // __has_builtin(__builtin_coro_noop)
|
||||
|
||||
// 17.12.5, trivial awaitables
|
||||
struct suspend_never {
|
||||
bool await_ready() const noexcept { return true; }
|
||||
void await_suspend(coroutine_handle<>) const noexcept {}
|
||||
void await_resume() const noexcept {}
|
||||
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 {
|
||||
bool await_ready() const noexcept { return false; }
|
||||
void await_suspend(coroutine_handle<>) const noexcept {}
|
||||
void await_resume() const noexcept {}
|
||||
constexpr bool await_ready() const noexcept { return false; }
|
||||
constexpr void await_suspend(coroutine_handle<>) const noexcept {}
|
||||
constexpr void await_resume() const noexcept {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// 17.12.3.7, hash support
|
||||
template <class _Tp>
|
||||
struct hash<experimental::coroutine_handle<_Tp> > {
|
||||
using argument_type = experimental::coroutine_handle<_Tp>;
|
||||
using result_type = size_t;
|
||||
using __arg_type = experimental::coroutine_handle<_Tp>;
|
||||
size_t operator()(__arg_type const& __v) const noexcept
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user