xref: /llvm-project/clang/test/CodeGenCoroutines/Inputs/coroutine-exp-namespace.h (revision ec117158a390a0ebf64377caa5abd0c976df8f7a)
1 #pragma once
2 
3 namespace std {
4 namespace experimental {
5 inline namespace coroutines_v1 {
6 
7 template <typename R, typename...> struct coroutine_traits {
8   using promise_type = typename R::promise_type;
9 };
10 
11 template <typename Promise = void> struct coroutine_handle;
12 
13 template <> struct coroutine_handle<void> {
14   static coroutine_handle from_address(void *addr) noexcept {
15     coroutine_handle me;
16     me.ptr = addr;
17     return me;
18   }
19   void operator()() { resume(); }
20   void *address() const noexcept { return ptr; }
21   void resume() const { __builtin_coro_resume(ptr); }
22   void destroy() const { __builtin_coro_destroy(ptr); }
23   bool done() const { return __builtin_coro_done(ptr); }
24   coroutine_handle &operator=(decltype(nullptr)) {
25     ptr = nullptr;
26     return *this;
27   }
28   coroutine_handle(decltype(nullptr)) : ptr(nullptr) {}
29   coroutine_handle() : ptr(nullptr) {}
30   //  void reset() { ptr = nullptr; } // add to P0057?
31   explicit operator bool() const { return ptr; }
32 
33 protected:
34   void *ptr;
35 };
36 
37 template <typename Promise> struct coroutine_handle : coroutine_handle<> {
38   using coroutine_handle<>::operator=;
39 
40   static coroutine_handle from_address(void *addr) noexcept {
41     coroutine_handle me;
42     me.ptr = addr;
43     return me;
44   }
45 
46   Promise &promise() const {
47     return *reinterpret_cast<Promise *>(
48         __builtin_coro_promise(ptr, alignof(Promise), false));
49   }
50   static coroutine_handle from_promise(Promise &promise) {
51     coroutine_handle p;
52     p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true);
53     return p;
54   }
55 };
56 
57 template <typename _PromiseT>
58 bool operator==(coroutine_handle<_PromiseT> const &_Left,
59                 coroutine_handle<_PromiseT> const &_Right) noexcept {
60   return _Left.address() == _Right.address();
61 }
62 
63 template <typename _PromiseT>
64 bool operator!=(coroutine_handle<_PromiseT> const &_Left,
65                 coroutine_handle<_PromiseT> const &_Right) noexcept {
66   return !(_Left == _Right);
67 }
68 
69 struct suspend_always {
70   bool await_ready() { return false; }
71   void await_suspend(coroutine_handle<>) {}
72   void await_resume() {}
73 };
74 struct suspend_never {
75   bool await_ready() noexcept { return true; }
76   void await_suspend(coroutine_handle<>) noexcept {}
77   void await_resume() noexcept {}
78 };
79 
80 } // namespace coroutines_v1
81 } // namespace experimental
82 } // namespace std
83