xref: /llvm-project/clang/test/AST/Inputs/std-coroutine.h (revision 8d60e10ce4bd428577ef441eb77b260ec3c14088)
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wno-unreachable-code -Wno-unused-value
2 #ifndef STD_COROUTINE_H
3 #define STD_COROUTINE_H
4 
5 namespace std {
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 struct suspend_always {
58   bool await_ready() noexcept { return false; }
59   void await_suspend(coroutine_handle<>) noexcept {}
60   void await_resume() noexcept {}
61 };
62 
63 struct suspend_never {
64   bool await_ready() noexcept { return true; }
65   void await_suspend(coroutine_handle<>) noexcept {}
66   void await_resume() noexcept {}
67 };
68 
69 } // namespace std
70 
71 #endif // STD_COROUTINE_H
72