Skip to content

Instantly share code, notes, and snippets.

@dascandy
Created May 29, 2020 07:40
Show Gist options
  • Select an option

  • Save dascandy/20a0c890dc565f6fadffda0bd268f5b5 to your computer and use it in GitHub Desktop.

Select an option

Save dascandy/20a0c890dc565f6fadffda0bd268f5b5 to your computer and use it in GitHub Desktop.
Freestanding experimental/coroutine
#pragma once
namespace std {
template <typename T> struct remove_cv { using type = T; };
template <typename T> struct remove_cv<const T> { using type = T; };
template <typename T> struct remove_cv<volatile T> { using type = T; };
template <typename T> struct remove_cv<const volatile T> { using type = T; };
template <typename T> using remove_cv_t = typename remove_cv<T>::type;
namespace experimental {
template<typename R, typename... ArgTypes>
struct coroutine_traits {
using promise_type = typename R::promise_type;
};
template<class Promise = void>
struct coroutine_handle;
template<>
struct coroutine_handle<void>
{
constexpr coroutine_handle() noexcept
: ptr(nullptr)
{
}
constexpr coroutine_handle(nullptr_t) noexcept
: ptr(nullptr)
{
}
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) {
return coroutine_handle{addr};
}
constexpr explicit operator bool() const noexcept {
return ptr != nullptr;
}
bool done() const;
void operator()() const;
void resume() const {
__builtin_coro_resume(ptr);
}
void destroy() const;
public:
constexpr coroutine_handle(void* p) noexcept
: ptr(p)
{}
void* ptr;
};
template<class Promise>
struct coroutine_handle : coroutine_handle<>
{
using coroutine_handle<>::coroutine_handle;
static coroutine_handle from_promise(Promise&p) {
using RawPromise = typename std::remove_cv_t<Promise>;
coroutine_handle __tmp;
__tmp.ptr = __builtin_coro_promise(&const_cast<RawPromise&>(p), alignof(Promise), true);
return __tmp;
}
coroutine_handle& operator=(nullptr_t) noexcept {
ptr = nullptr;
return *this;
}
static constexpr coroutine_handle from_address(void* addr) {
return coroutine_handle{addr};
}
Promise& promise() const {
}
};
constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept;
// constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;
template<class T> struct hash;
template<class P> struct hash<coroutine_handle<P>>;
struct noop_coroutine_promise;
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
noop_coroutine_handle noop_coroutine() noexcept;
struct suspend_never {
bool await_ready() {
return true;
}
void await_suspend(std::experimental::coroutine_handle<> awaiting) {}
void await_resume() {}
};
struct suspend_always {
bool await_ready() {
return false;
}
void await_suspend(std::experimental::coroutine_handle<> awaiting) {}
void await_resume() {}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment