1 // { dg-do run } 2 3 #include "../coro.h" 4 5 struct pt_b 6 { initial_suspendpt_b7 std::suspend_never initial_suspend() const noexcept { return {}; } final_suspendpt_b8 std::suspend_never final_suspend() const noexcept { return {}; } unhandled_exceptionpt_b9 void unhandled_exception() const noexcept {} 10 }; 11 12 int called_rv_op = 0; 13 int v; 14 15 struct pt_c : pt_b 16 { 17 struct rv 18 { operatorpt_c::rv19 void operator ()(int x){ 20 PRINTF("call to operator ret val with %d\n", x); 21 called_rv_op++; 22 v = x; 23 // int val () { return x; } 24 } 25 }; 26 using handle_t = std::coroutine_handle<pt_c>; get_return_objectpt_c27 auto get_return_object() noexcept { return handle_t::from_promise(*this); } 28 rv return_value; 29 }; 30 31 int called_lambda = 0; 32 33 struct pt_d : pt_b 34 { 35 using handle_t = std::coroutine_handle<pt_d>; get_return_objectpt_d36 auto get_return_object() noexcept { return handle_t::from_promise(*this); } 37 static constexpr auto return_value 38 = [] (int x) { PRINTF("call to lambda ret val %d\n", x); called_lambda++; v = x;}; 39 }; 40 41 template <> struct std::coroutine_traits<pt_c::handle_t> 42 { using promise_type = pt_c; }; 43 44 static pt_c::handle_t foo () 45 { 46 co_return 5; 47 } 48 49 template <> struct std::coroutine_traits<pt_d::handle_t> 50 { using promise_type = pt_d; }; 51 52 static pt_d::handle_t bar () 53 { 54 co_return 3; 55 } 56 57 int main () 58 { 59 /* These 'coroutines' run to completion imediately, like a regular fn. */ 60 foo (); 61 if (v != 5) 62 { 63 PRINT ("foo failed to set v"); 64 abort (); 65 } 66 67 bar (); 68 if (v != 3) 69 { 70 PRINT ("bar failed to set v"); 71 abort (); 72 } 73 74 75 if (called_rv_op != 1 || called_lambda != 1) 76 { 77 PRINT ("Failed to call one of the return_value cases"); 78 abort (); 79 } 80 } 81