Browse Source

按照

ISO/IEC JTC1 SC22 WG21 N4860
(Date: 2020-03-31)
标准为clang实现coroutine头文件
tags/2.9.10
tearshark 4 years ago
parent
commit
11f1df9a11
2 changed files with 61 additions and 55 deletions
  1. 2
    0
      librf/src/unix/clang_builtin.h
  2. 59
    55
      librf/src/unix/coroutine.h

+ 2
- 0
librf/src/unix/clang_builtin.h View File



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);

+ 59
- 55
librf/src/unix/coroutine.h View File

#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"
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 {
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_; }

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; 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);
} }


"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.
void* __handle_; 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(); 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> 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
// 18.11.2.1 construct/reset
// 17.12.3.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;
// 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);
} }


} }
}; };


// 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>
: public coroutine_handle<> {
class coroutine_handle<noop_coroutine_promise> : 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 {}
}; };


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; }
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 { 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> 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…
Cancel
Save