1 struct coro1 { 2 3 struct promise_type { 4 promise_typecoro1::promise_type5 promise_type () : vv(-1) { PRINT ("Promise def. CTOR"); } promise_typecoro1::promise_type6 promise_type (int __x) : vv(__x) { PRINTF ("promise_type1 with %d\n",__x); } promise_typecoro1::promise_type7 promise_type (int __x, int& __y, int&& __z) 8 : vv(__x), v2(__y), v3(__z) 9 { PRINTF ("promise_type2 with %d, %d, %d\n", __x, __y, __z); } promise_typecoro1::promise_type10 promise_type (int __x, int& __y, int& __z) 11 : vv(__x), v2(__y), v3(__z) 12 { PRINTF ("promise_type3 with %d, %d, %d\n", __x, __y, __z); } 13 ~promise_typecoro1::promise_type14 ~promise_type() { PRINT ("Destroyed Promise"); } 15 get_return_objectcoro1::promise_type16 auto get_return_object () { 17 PRINT ("get_return_object: handle from promise"); 18 return handle_type::from_promise (*this); 19 } 20 initial_suspendcoro1::promise_type21 auto initial_suspend () { 22 PRINT ("get initial_suspend (always)"); 23 return suspend_always_prt{}; 24 } final_suspendcoro1::promise_type25 auto final_suspend () noexcept { 26 PRINT ("get final_suspend (always)"); 27 return suspend_always_prt{}; 28 } 29 30 #ifdef USE_AWAIT_TRANSFORM 31 await_transformcoro1::promise_type32 auto await_transform (int v) { 33 PRINTF ("await_transform an int () %d\n",v); 34 return suspend_always_intprt (v); 35 } 36 await_transformcoro1::promise_type37 auto await_transform (long v) { 38 PRINTF ("await_transform a long () %ld\n",v); 39 return suspend_always_longprtsq (v); 40 } 41 42 #endif 43 yield_valuecoro1::promise_type44 auto yield_value (int v) { 45 PRINTF ("yield_value (%d)\n", v); 46 vv = v; 47 return suspend_always_prt{}; 48 } 49 return_valuecoro1::promise_type50 void return_value (int v) { 51 PRINTF ("return_value (%d)\n", v); 52 vv = v; 53 54 } 55 unhandled_exceptioncoro1::promise_type56 void unhandled_exception() { PRINT ("** unhandled exception"); } 57 get_valuecoro1::promise_type58 int get_value () { return vv; } get_v2coro1::promise_type59 int get_v2 () { return v2; } get_v3coro1::promise_type60 int get_v3 () { return v3; } 61 62 private: 63 int vv; 64 int v2; 65 int v3; 66 }; 67 68 using handle_type = coro::coroutine_handle<coro1::promise_type>; 69 handle_type handle; coro1coro170 coro1 () : handle(0) {} coro1coro171 coro1 (handle_type _handle) 72 : handle(_handle) { 73 PRINT("Created coro1 object from handle"); 74 } 75 coro1 (const coro1 &) = delete; // no copying coro1coro176 coro1 (coro1 &&s) : handle(s.handle) { 77 s.handle = nullptr; 78 PRINT("coro1 mv ctor "); 79 } 80 coro1 &operator = (coro1 &&s) { 81 handle = s.handle; 82 s.handle = nullptr; 83 PRINT("coro1 op= "); 84 return *this; 85 } ~coro1coro186 ~coro1() { 87 PRINT("Destroyed coro1"); 88 if ( handle ) 89 handle.destroy(); 90 } 91 92 // Some awaitables to use in tests. 93 // With progress printing for debug. 94 struct suspend_never_prt { await_readycoro1::suspend_never_prt95 bool await_ready() const noexcept { return true; } await_suspendcoro1::suspend_never_prt96 void await_suspend(handle_type) const noexcept { PRINT ("susp-never-susp");} await_resumecoro1::suspend_never_prt97 void await_resume() const noexcept { PRINT ("susp-never-resume");} 98 }; 99 100 struct suspend_always_prt { await_readycoro1::suspend_always_prt101 bool await_ready() const noexcept { return false; } await_suspendcoro1::suspend_always_prt102 void await_suspend(handle_type) const noexcept { PRINT ("susp-always-susp");} await_resumecoro1::suspend_always_prt103 void await_resume() const noexcept { PRINT ("susp-always-resume");} ~suspend_always_prtcoro1::suspend_always_prt104 ~suspend_always_prt() { PRINT ("susp-always-dtor"); } 105 }; 106 107 struct suspend_always_intprt { 108 int x; suspend_always_intprtcoro1::suspend_always_intprt109 suspend_always_intprt() : x(5) {} suspend_always_intprtcoro1::suspend_always_intprt110 suspend_always_intprt(int __x) : x(__x) {} ~suspend_always_intprtcoro1::suspend_always_intprt111 ~suspend_always_intprt() {} await_readycoro1::suspend_always_intprt112 bool await_ready() const noexcept { return false; } await_suspendcoro1::suspend_always_intprt113 void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("susp-always-susp-intprt");} await_resumecoro1::suspend_always_intprt114 int await_resume() const noexcept { PRINT ("susp-always-resume-intprt"); return x;} 115 }; 116 117 /* This returns the square of the int that it was constructed with. */ 118 struct suspend_always_longprtsq { 119 long x; suspend_always_longprtsqcoro1::suspend_always_longprtsq120 suspend_always_longprtsq() : x(12L) { PRINT ("suspend_always_longprtsq def ctor"); } suspend_always_longprtsqcoro1::suspend_always_longprtsq121 suspend_always_longprtsq(long _x) : x(_x) { PRINTF ("suspend_always_longprtsq ctor with %ld\n", x); } ~suspend_always_longprtsqcoro1::suspend_always_longprtsq122 ~suspend_always_longprtsq() {} await_readycoro1::suspend_always_longprtsq123 bool await_ready() const noexcept { return false; } await_suspendcoro1::suspend_always_longprtsq124 void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("susp-always-susp-longsq");} await_resumecoro1::suspend_always_longprtsq125 long await_resume() const noexcept { PRINT ("susp-always-resume-longsq"); return x * x;} 126 }; 127 128 struct suspend_always_intrefprt { 129 int& x; suspend_always_intrefprtcoro1::suspend_always_intrefprt130 suspend_always_intrefprt(int& __x) : x(__x) {} ~suspend_always_intrefprtcoro1::suspend_always_intrefprt131 ~suspend_always_intrefprt() {} await_readycoro1::suspend_always_intrefprt132 bool await_ready() const noexcept { return false; } await_suspendcoro1::suspend_always_intrefprt133 void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("susp-always-susp-intprt");} await_resumecoro1::suspend_always_intrefprt134 int& await_resume() const noexcept { PRINT ("susp-always-resume-intprt"); return x;} 135 }; 136 137 template <typename _AwaitType> 138 struct suspend_always_tmpl_awaiter { 139 _AwaitType x; suspend_always_tmpl_awaitercoro1::suspend_always_tmpl_awaiter140 suspend_always_tmpl_awaiter(_AwaitType __x) : x(__x) {} ~suspend_always_tmpl_awaitercoro1::suspend_always_tmpl_awaiter141 ~suspend_always_tmpl_awaiter() {} await_readycoro1::suspend_always_tmpl_awaiter142 bool await_ready() const noexcept { return false; } await_suspendcoro1::suspend_always_tmpl_awaiter143 void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("suspend_always_tmpl_awaiter");} await_resumecoro1::suspend_always_tmpl_awaiter144 _AwaitType await_resume() const noexcept { PRINT ("suspend_always_tmpl_awaiter"); return x;} 145 }; 146 147 }; 148