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