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 {} return_voidpt_b10 constexpr static void return_void () noexcept {} 11 }; 12 13 int called_yv_op = 0; 14 int v; 15 16 struct pt_c : pt_b 17 { 18 struct yv 19 { operatorpt_c::yv20 auto operator ()(int x){ 21 PRINTF("call to operator yield val with %d\n", x); 22 called_yv_op++; 23 v = x; 24 return std::suspend_never{}; 25 } 26 }; 27 using handle_t = std::coroutine_handle<pt_c>; get_return_objectpt_c28 auto get_return_object() noexcept { return handle_t::from_promise(*this); } 29 yv yield_value; 30 }; 31 32 int called_lambda = 0; 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 yield_value = [] (int x) -> std::suspend_never 38 { 39 PRINTF("call to lambda yield val %d\n", x); 40 called_lambda++; 41 v = x; 42 return {}; 43 }; 44 }; 45 46 template <> struct std::coroutine_traits<pt_c::handle_t> 47 { using promise_type = pt_c; }; 48 49 static pt_c::handle_t foo () 50 { 51 co_yield 5; 52 } 53 54 template <> struct std::coroutine_traits<pt_d::handle_t> 55 { using promise_type = pt_d; }; 56 57 static pt_d::handle_t bar () 58 { 59 co_yield 3; 60 } 61 62 int main () 63 { 64 /* These 'coroutines' run to completion imediately, like a regular fn. */ 65 foo (); 66 if (v != 5) 67 { 68 PRINT ("foo failed to yield v"); 69 abort (); 70 } 71 72 bar (); 73 if (v != 3) 74 { 75 PRINT ("bar failed to yield v"); 76 abort (); 77 } 78 79 if (called_yv_op != 1 || called_lambda != 1) 80 { 81 PRINT ("Failed to call one of the yield_value cases"); 82 abort (); 83 } 84 } 85