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" size_t __builtin_coro_size();
|
||||||
extern "C" void* __builtin_coro_frame();
|
extern "C" void* __builtin_coro_frame();
|
||||||
|
extern "C" void* __builtin_coro_noop();
|
||||||
extern "C" void* __builtin_coro_free(void* coro_frame);
|
extern "C" void* __builtin_coro_free(void* coro_frame);
|
||||||
#pragma intrinsic(__builtin_coro_size)
|
#pragma intrinsic(__builtin_coro_size)
|
||||||
#pragma intrinsic(__builtin_coro_frame)
|
#pragma intrinsic(__builtin_coro_frame)
|
||||||
|
#pragma intrinsic(__builtin_coro_noop)
|
||||||
#pragma intrinsic(__builtin_coro_free)
|
#pragma intrinsic(__builtin_coro_free)
|
||||||
|
|
||||||
extern "C" void* __builtin_coro_id(int align, void* promise, void* fnaddr, void* parts);
|
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 <memory> // for hash<T*>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <compare>
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#include "clang_builtin.h"
|
#include "clang_builtin.h"
|
||||||
@ -80,17 +81,21 @@ namespace std {
|
|||||||
using promise_type = typename _Tp::promise_type;
|
using promise_type = typename _Tp::promise_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 17.12.2, coroutine traits
|
||||||
template <typename _Ret, typename... _Args>
|
template <typename _Ret, typename... _Args>
|
||||||
struct coroutine_traits : public __coroutine_traits_sfinae<_Ret>
|
struct coroutine_traits : public __coroutine_traits_sfinae<_Ret>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 17.12.3, coroutine handle
|
||||||
template <typename _Promise = void>
|
template <typename _Promise = void>
|
||||||
class coroutine_handle;
|
class coroutine_handle;
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class coroutine_handle<void> {
|
class coroutine_handle<void>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
// 17.12.3.1, construct/reset
|
||||||
constexpr coroutine_handle() noexcept : __handle_(nullptr) {}
|
constexpr coroutine_handle() noexcept : __handle_(nullptr) {}
|
||||||
constexpr coroutine_handle(nullptr_t) noexcept : __handle_(nullptr) {}
|
constexpr coroutine_handle(nullptr_t) noexcept : __handle_(nullptr) {}
|
||||||
coroutine_handle& operator=(nullptr_t) noexcept {
|
coroutine_handle& operator=(nullptr_t) noexcept {
|
||||||
@ -98,28 +103,15 @@ namespace std {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 17.12.3.2, export/import
|
||||||
constexpr void* address() const noexcept { return __handle_; }
|
constexpr void* address() const noexcept { return __handle_; }
|
||||||
constexpr explicit operator bool() const noexcept { return __handle_; }
|
static constexpr coroutine_handle from_address(void* __addr) noexcept {
|
||||||
|
|
||||||
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 {
|
|
||||||
coroutine_handle __tmp;
|
coroutine_handle __tmp;
|
||||||
__tmp.__handle_ = __addr;
|
__tmp.__handle_ = __addr;
|
||||||
return __tmp;
|
return __tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Should from_address(nullptr) be allowed?
|
// 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);
|
return coroutine_handle(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +122,22 @@ namespace std {
|
|||||||
"non-void pointers");
|
"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:
|
private:
|
||||||
bool __is_suspended() const noexcept {
|
bool __is_suspended() const noexcept {
|
||||||
// FIXME actually implement a check for if the coro is suspended.
|
// FIXME actually implement a check for if the coro is suspended.
|
||||||
@ -142,50 +150,35 @@ namespace std {
|
|||||||
void* __handle_;
|
void* __handle_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 18.11.2.7 comparison operators:
|
// 17.12.3.6, comparison operators
|
||||||
inline bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||||
return __x.address() == __y.address();
|
return __x.address() == __y.address();
|
||||||
}
|
}
|
||||||
inline bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
|
||||||
return !(__x == __y);
|
return __x.address() <=> __y.address();
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Promise>
|
template <typename _Promise>
|
||||||
class coroutine_handle : public coroutine_handle<> {
|
class coroutine_handle : public coroutine_handle<>
|
||||||
|
{
|
||||||
using _Base = coroutine_handle<>;
|
using _Base = coroutine_handle<>;
|
||||||
public:
|
public:
|
||||||
#ifndef _LIBCPP_CXX03_LANG
|
// 17.12.3.1, construct/reset
|
||||||
// 18.11.2.1 construct/reset
|
|
||||||
using coroutine_handle<>::coroutine_handle;
|
using coroutine_handle<>::coroutine_handle;
|
||||||
#else
|
|
||||||
coroutine_handle() noexcept : _Base() {}
|
|
||||||
coroutine_handle(nullptr_t) noexcept : _Base(nullptr) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
coroutine_handle& operator=(nullptr_t) noexcept {
|
coroutine_handle& operator=(nullptr_t) noexcept {
|
||||||
_Base::operator=(nullptr);
|
_Base::operator=(nullptr);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 17.12.3.5, promise access
|
||||||
_Promise& promise() const {
|
_Promise& promise() const {
|
||||||
return *static_cast<_Promise*>(
|
return *static_cast<_Promise*>(
|
||||||
__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
|
__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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;
|
coroutine_handle __tmp;
|
||||||
__tmp.__handle_ = __addr;
|
__tmp.__handle_ = __addr;
|
||||||
return __tmp;
|
return __tmp;
|
||||||
@ -195,7 +188,7 @@ namespace std {
|
|||||||
// the deleted _Promise* overload doesn't make from_address(nullptr)
|
// the deleted _Promise* overload doesn't make from_address(nullptr)
|
||||||
// ambiguous.
|
// ambiguous.
|
||||||
// FIXME: should from_address work with nullptr?
|
// 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);
|
return coroutine_handle(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,23 +216,32 @@ namespace std {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 17.12.4, no-op coroutines
|
||||||
#if __has_builtin(__builtin_coro_noop)
|
#if __has_builtin(__builtin_coro_noop)
|
||||||
struct noop_coroutine_promise {};
|
struct noop_coroutine_promise {};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class coroutine_handle<noop_coroutine_promise>
|
class coroutine_handle<noop_coroutine_promise> : public coroutine_handle<>
|
||||||
: public coroutine_handle<> {
|
{
|
||||||
using _Base = coroutine_handle<>;
|
using _Base = coroutine_handle<>;
|
||||||
using _Promise = noop_coroutine_promise;
|
using _Promise = noop_coroutine_promise;
|
||||||
public:
|
public:
|
||||||
_Promise& promise() const {
|
// 17.12.4.2.3, promise access
|
||||||
|
_Promise& promise() const noexcept {
|
||||||
return *static_cast<_Promise*>(
|
return *static_cast<_Promise*>(
|
||||||
__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
|
__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 explicit operator bool() const noexcept { return true; }
|
||||||
constexpr bool done() const noexcept { return false; }
|
constexpr bool done() const noexcept { return false; }
|
||||||
|
|
||||||
|
// 17.12.4.2.2, resumption
|
||||||
constexpr void operator()() const noexcept {}
|
constexpr void operator()() const noexcept {}
|
||||||
constexpr void resume() const noexcept {}
|
constexpr void resume() const noexcept {}
|
||||||
constexpr void destroy() const noexcept {}
|
constexpr void destroy() const noexcept {}
|
||||||
@ -251,28 +253,30 @@ namespace std {
|
|||||||
};
|
};
|
||||||
|
|
||||||
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
|
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
|
||||||
|
|
||||||
inline noop_coroutine_handle noop_coroutine() noexcept {
|
inline noop_coroutine_handle noop_coroutine() noexcept {
|
||||||
return noop_coroutine_handle();
|
return noop_coroutine_handle();
|
||||||
}
|
}
|
||||||
#endif // __has_builtin(__builtin_coro_noop)
|
#endif // __has_builtin(__builtin_coro_noop)
|
||||||
|
|
||||||
|
// 17.12.5, trivial awaitables
|
||||||
struct suspend_never {
|
struct suspend_never {
|
||||||
bool await_ready() const noexcept { return true; }
|
constexpr bool await_ready() const noexcept { return true; }
|
||||||
void await_suspend(coroutine_handle<>) const noexcept {}
|
constexpr void await_suspend(coroutine_handle<>) const noexcept {}
|
||||||
void await_resume() const noexcept {}
|
constexpr void await_resume() const noexcept {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct suspend_always {
|
struct suspend_always {
|
||||||
bool await_ready() const noexcept { return false; }
|
constexpr bool await_ready() const noexcept { return false; }
|
||||||
void await_suspend(coroutine_handle<>) const noexcept {}
|
constexpr void await_suspend(coroutine_handle<>) const noexcept {}
|
||||||
void await_resume() const noexcept {}
|
constexpr void await_resume() const noexcept {}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 17.12.3.7, hash support
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
struct hash<experimental::coroutine_handle<_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>;
|
using __arg_type = experimental::coroutine_handle<_Tp>;
|
||||||
size_t operator()(__arg_type const& __v) const noexcept
|
size_t operator()(__arg_type const& __v) const noexcept
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user