1 #if __has_include(<coroutine>) 2 3 #include <coroutine> 4 5 # if __clang__ 6 # include <utility> 7 # endif 8 9 namespace coro = std; 10 11 #elif __has_include(<experimental/coroutine>) 12 13 #include <experimental/coroutine> 14 15 # if __clang__ 16 # include <utility> 17 # endif 18 19 namespace coro = std::experimental; 20 21 #else 22 23 #warning "no installed coroutine headers found, using test-suite local one" 24 25 /* Dummy version to allow tests without an installed header. */ 26 # ifndef __TESTSUITE_CORO_H_n4835 27 # define __TESTSUITE_CORO_H_n4835 28 29 // Fragments (with short-cuts) to mimic enough of the library header to 30 // make some progress. 31 32 # if __cpp_impl_coroutine 33 34 namespace std { 35 inline namespace __n4861 { 36 37 // 21.11.1 coroutine traits 38 template<typename _R, typename...> struct coroutine_traits { 39 using promise_type = typename _R::promise_type; 40 }; 41 42 // 21.11.2 coroutine handle 43 template <typename Promise = void> struct coroutine_handle; 44 45 template <> 46 struct coroutine_handle<void> { 47 public: 48 // 21.11.2.1 construct/reset 49 constexpr coroutine_handle () noexcept 50 : __fr_ptr (0) {} 51 constexpr coroutine_handle (decltype(nullptr) __h) noexcept 52 : __fr_ptr (__h) {} 53 coroutine_handle &operator= (decltype(nullptr)) noexcept { 54 __fr_ptr = nullptr; 55 return *this; 56 } 57 58 public: 59 // 21.11.2.2 export/import 60 constexpr void *address () const noexcept { return __fr_ptr; } 61 constexpr static coroutine_handle from_address (void *__a) noexcept { 62 coroutine_handle __self; 63 __self.__fr_ptr = __a; 64 return __self; 65 } 66 public: 67 // 21.11.2.3 observers 68 constexpr explicit operator bool () const noexcept { 69 return bool (__fr_ptr); 70 } 71 bool done () const noexcept { 72 return __builtin_coro_done (__fr_ptr); 73 } 74 // 21.11.2.4 resumption 75 void operator () () const { resume (); } 76 void resume () const { 77 __builtin_coro_resume (__fr_ptr); 78 } 79 void destroy () const { 80 __builtin_coro_destroy (__fr_ptr); 81 } 82 protected: 83 void *__fr_ptr; 84 }; 85 86 template <class _Promise> 87 struct coroutine_handle : coroutine_handle<> { 88 // 21.11.2.1 construct/reset 89 using coroutine_handle<>::coroutine_handle; 90 static coroutine_handle from_promise(_Promise &p) { 91 coroutine_handle __self; 92 __self.__fr_ptr = 93 __builtin_coro_promise((char *)&p, __alignof(_Promise), true); 94 return __self; 95 } 96 coroutine_handle& operator=(decltype(nullptr)) noexcept { 97 coroutine_handle<>::operator=(nullptr); 98 return *this; 99 } 100 // 21.11.2.2 export/import 101 constexpr static coroutine_handle from_address(void* __a){ 102 coroutine_handle __self; 103 __self.__fr_ptr = __a; 104 return __self; 105 } 106 // 21.11.2.5 promise access 107 _Promise& promise() const { 108 void * __t = __builtin_coro_promise(this->__fr_ptr, 109 __alignof(_Promise), false); 110 return *static_cast<_Promise*>(__t); 111 } 112 }; 113 114 // n4760 - 21.11.5 trivial awaitables 115 116 struct suspend_always { 117 bool await_ready() { return false; } 118 void await_suspend(coroutine_handle<>) {} 119 void await_resume() {} 120 }; 121 122 struct suspend_never { 123 bool await_ready() { return true; } 124 void await_suspend(coroutine_handle<>) {} 125 void await_resume() {} 126 }; 127 128 } // namespace __n4861 129 } // namespace std 130 131 namespace coro = std; 132 133 # else 134 # error "coro.h requires support for coroutines, add -fcoroutines" 135 # endif 136 # endif // __TESTSUITE_CORO_H_n4835 137 138 #endif // __has_include(<experimental/coroutine>) 139 140 /* just to avoid cluttering dump files. */ 141 extern "C" int puts (const char *); 142 extern "C" int printf (const char *, ...); 143 144 #include <cstdlib> /* for abort () */ 145 146 #ifndef OUTPUT 147 # define PRINT(X) 148 # define PRINTF (void) 149 #else 150 # define PRINT(X) puts(X) 151 # define PRINTF printf 152 #endif 153