| struct coro1 { |
| |
| struct promise_type { |
| |
| promise_type () : vv(-1) { PRINT ("Promise def. CTOR"); } |
| promise_type (int __x) : vv(__x) { PRINTF ("promise_type1 with %d\n",__x); } |
| promise_type (int __x, int& __y, int&& __z) |
| : vv(__x), v2(__y), v3(__z) |
| { PRINTF ("promise_type2 with %d, %d, %d\n", __x, __y, __z); } |
| promise_type (int __x, int& __y, int& __z) |
| : vv(__x), v2(__y), v3(__z) |
| { PRINTF ("promise_type3 with %d, %d, %d\n", __x, __y, __z); } |
| |
| ~promise_type() { PRINT ("Destroyed Promise"); } |
| |
| auto get_return_object () { |
| PRINT ("get_return_object: handle from promise"); |
| return handle_type::from_promise (*this); |
| } |
| |
| auto initial_suspend () { |
| PRINT ("get initial_suspend (always)"); |
| return suspend_always_prt{}; |
| } |
| auto final_suspend () noexcept { |
| PRINT ("get final_suspend (always)"); |
| return suspend_always_prt{}; |
| } |
| |
| #ifdef USE_AWAIT_TRANSFORM |
| |
| auto await_transform (int v) { |
| PRINTF ("await_transform an int () %d\n",v); |
| return suspend_always_intprt (v); |
| } |
| |
| auto await_transform (long v) { |
| PRINTF ("await_transform a long () %ld\n",v); |
| return suspend_always_longprtsq (v); |
| } |
| |
| #endif |
| |
| auto yield_value (int v) { |
| PRINTF ("yield_value (%d)\n", v); |
| vv = v; |
| return suspend_always_prt{}; |
| } |
| |
| void return_value (int v) { |
| PRINTF ("return_value (%d)\n", v); |
| vv = v; |
| |
| } |
| |
| void unhandled_exception() { PRINT ("** unhandled exception"); } |
| |
| int get_value () { return vv; } |
| int get_v2 () { return v2; } |
| int get_v3 () { return v3; } |
| |
| private: |
| int vv; |
| int v2; |
| int v3; |
| }; |
| |
| using handle_type = coro::coroutine_handle<coro1::promise_type>; |
| handle_type handle; |
| coro1 () : handle(0) {} |
| coro1 (handle_type _handle) |
| : handle(_handle) { |
| PRINT("Created coro1 object from handle"); |
| } |
| coro1 (const coro1 &) = delete; // no copying |
| coro1 (coro1 &&s) : handle(s.handle) { |
| s.handle = nullptr; |
| PRINT("coro1 mv ctor "); |
| } |
| coro1 &operator = (coro1 &&s) { |
| handle = s.handle; |
| s.handle = nullptr; |
| PRINT("coro1 op= "); |
| return *this; |
| } |
| ~coro1() { |
| PRINT("Destroyed coro1"); |
| if ( handle ) |
| handle.destroy(); |
| } |
| |
| // Some awaitables to use in tests. |
| // With progress printing for debug. |
| struct suspend_never_prt { |
| bool await_ready() const noexcept { return true; } |
| void await_suspend(handle_type) const noexcept { PRINT ("susp-never-susp");} |
| void await_resume() const noexcept { PRINT ("susp-never-resume");} |
| }; |
| |
| struct suspend_always_prt { |
| bool await_ready() const noexcept { return false; } |
| void await_suspend(handle_type) const noexcept { PRINT ("susp-always-susp");} |
| void await_resume() const noexcept { PRINT ("susp-always-resume");} |
| ~suspend_always_prt() { PRINT ("susp-always-dtor"); } |
| }; |
| |
| struct suspend_always_intprt { |
| int x; |
| suspend_always_intprt() : x(5) {} |
| suspend_always_intprt(int __x) : x(__x) {} |
| ~suspend_always_intprt() {} |
| bool await_ready() const noexcept { return false; } |
| void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("susp-always-susp-intprt");} |
| int await_resume() const noexcept { PRINT ("susp-always-resume-intprt"); return x;} |
| }; |
| |
| /* This returns the square of the int that it was constructed with. */ |
| struct suspend_always_longprtsq { |
| long x; |
| suspend_always_longprtsq() : x(12L) { PRINT ("suspend_always_longprtsq def ctor"); } |
| suspend_always_longprtsq(long _x) : x(_x) { PRINTF ("suspend_always_longprtsq ctor with %ld\n", x); } |
| ~suspend_always_longprtsq() {} |
| bool await_ready() const noexcept { return false; } |
| void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("susp-always-susp-longsq");} |
| long await_resume() const noexcept { PRINT ("susp-always-resume-longsq"); return x * x;} |
| }; |
| |
| struct suspend_always_intrefprt { |
| int& x; |
| suspend_always_intrefprt(int& __x) : x(__x) {} |
| ~suspend_always_intrefprt() {} |
| bool await_ready() const noexcept { return false; } |
| void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("susp-always-susp-intprt");} |
| int& await_resume() const noexcept { PRINT ("susp-always-resume-intprt"); return x;} |
| }; |
| |
| template <typename _AwaitType> |
| struct suspend_always_tmpl_awaiter { |
| _AwaitType x; |
| suspend_always_tmpl_awaiter(_AwaitType __x) : x(__x) {} |
| ~suspend_always_tmpl_awaiter() {} |
| bool await_ready() const noexcept { return false; } |
| void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("suspend_always_tmpl_awaiter");} |
| _AwaitType await_resume() const noexcept { PRINT ("suspend_always_tmpl_awaiter"); return x;} |
| }; |
| |
| }; |