152
|
1 // { dg-do run { target c++17 } }
|
|
2
|
|
3 #include "../coro.h"
|
|
4
|
|
5 class resumable {
|
|
6 public:
|
|
7 struct promise_type;
|
|
8 using coro_handle = std::coroutine_handle<promise_type>;
|
|
9 resumable(coro_handle handle) : handle_(handle) { }
|
|
10 resumable(resumable&) = delete;
|
|
11 resumable(resumable&&) = delete;
|
|
12 ~resumable() { handle_.destroy(); }
|
|
13 coro_handle handle_;
|
|
14 };
|
|
15
|
|
16 struct resumable::promise_type {
|
|
17 using coro_handle = std::coroutine_handle<promise_type>;
|
|
18 int used;
|
|
19 auto get_return_object() {
|
|
20 return coro_handle::from_promise(*this);
|
|
21 }
|
|
22 auto initial_suspend() { return std::suspend_never(); }
|
|
23 auto final_suspend() { return std::suspend_always(); }
|
|
24 void return_value(int x) {used = x;}
|
|
25 void unhandled_exception() {}
|
|
26
|
|
27 struct TestAwaiter {
|
|
28 int recent_test;
|
|
29 TestAwaiter(int test) : recent_test{test} {}
|
|
30 bool await_ready() { return false; }
|
|
31 void await_suspend(std::coroutine_handle<promise_type>) {}
|
|
32 int await_resume() {
|
|
33 return recent_test;
|
|
34 }
|
|
35 auto operator co_await() {
|
|
36 return *this;
|
|
37 }
|
|
38 };
|
|
39
|
|
40 struct TestAwaiterCH :TestAwaiter {
|
|
41 TestAwaiterCH(int test) : TestAwaiter(test) {};
|
|
42 };
|
|
43
|
|
44 struct TestAwaiterCHCH :TestAwaiterCH {
|
|
45 TestAwaiterCHCH(int test) : TestAwaiterCH(test) {};
|
|
46
|
|
47 resumable foo(){
|
|
48 int x = co_await *this;
|
|
49 co_return x;
|
|
50 }
|
|
51 };
|
|
52 };
|
|
53
|
|
54 struct TestP {
|
|
55 resumable::promise_type::TestAwaiterCHCH tp = resumable::promise_type::TestAwaiterCHCH(6);
|
|
56 };
|
|
57
|
|
58 resumable foo1(int t){
|
|
59 int x = co_await resumable::promise_type::TestAwaiterCH(t);
|
|
60 co_return x;
|
|
61 }
|
|
62
|
|
63 resumable foo2(){
|
|
64 struct TestP TP;
|
|
65 int x = co_await TP.tp;
|
|
66 co_return x;
|
|
67 }
|
|
68
|
|
69 resumable foo3(){
|
|
70 int x = co_await TestP{}.tp;
|
|
71 co_return x;
|
|
72 }
|
|
73
|
|
74 int main(){
|
|
75 auto t = resumable::promise_type::TestAwaiterCHCH(4);
|
|
76 resumable res = t.foo();
|
|
77 while (!res.handle_.done())
|
|
78 res.handle_.resume();
|
|
79 if (res.handle_.promise().used != 4)
|
|
80 abort();
|
|
81
|
|
82 resumable res1 = foo1(5);
|
|
83 while (!res1.handle_.done())
|
|
84 res1.handle_.resume();
|
|
85 if (res1.handle_.promise().used != 5)
|
|
86 abort();
|
|
87
|
|
88 resumable res2 = foo2();
|
|
89 while (!res2.handle_.done())
|
|
90 res2.handle_.resume();
|
|
91 if (res2.handle_.promise().used != 6)
|
|
92 abort();
|
|
93
|
|
94 resumable res3 = foo2();
|
|
95 while (!res3.handle_.done())
|
|
96 res3.handle_.resume();
|
|
97 if (res3.handle_.promise().used != 6)
|
|
98 abort();
|
|
99 }
|