Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/g++.dg/coroutines/torture/co-yield-04-complex-local-state.C @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 // { dg-do run } | |
2 | |
3 // using non-trivial types in the coro. | |
4 | |
5 # include "../coro.h" | |
6 | |
7 #include <vector> | |
8 #include <string> | |
9 | |
10 template <typename T> | |
11 struct looper { | |
12 | |
13 struct promise_type { | |
14 T value; | |
15 promise_type() { PRINT ("Created Promise"); } | |
16 ~promise_type() { PRINT ("Destroyed Promise"); } | |
17 | |
18 auto get_return_object () { | |
19 PRINT ("get_return_object: handle from promise"); | |
20 return handle_type::from_promise (*this); | |
21 } | |
22 | |
23 auto initial_suspend () { | |
24 PRINT ("get initial_suspend (always)"); | |
25 return suspend_always_prt{}; | |
26 } | |
27 | |
28 auto final_suspend () { | |
29 PRINT ("get final_suspend (always)"); | |
30 return suspend_always_prt{}; | |
31 } | |
32 | |
33 void return_value (T v) { | |
34 PRINTF ("return_value () %s\n", v.c_str()); | |
35 value = v; | |
36 } | |
37 | |
38 auto yield_value (T v) { | |
39 PRINTF ("yield_value () %s and suspend always\n", v.c_str()); | |
40 value = v; | |
41 return suspend_always_prt{}; | |
42 } | |
43 | |
44 T get_value (void) { return value; } | |
45 | |
46 void unhandled_exception() { PRINT ("** unhandled exception"); } | |
47 }; | |
48 | |
49 using handle_type = coro::coroutine_handle<looper::promise_type>; | |
50 handle_type handle; | |
51 | |
52 looper () : handle(0) {} | |
53 looper (handle_type _handle) | |
54 : handle(_handle) { | |
55 PRINT("Created coro1 object from handle"); | |
56 } | |
57 looper (const looper &) = delete; // no copying | |
58 looper (looper &&s) : handle(s.handle) { | |
59 s.handle = nullptr; | |
60 PRINT("looper mv ctor "); | |
61 } | |
62 looper &operator = (looper &&s) { | |
63 handle = s.handle; | |
64 s.handle = nullptr; | |
65 PRINT("looper op= "); | |
66 return *this; | |
67 } | |
68 ~looper() { | |
69 PRINT("Destroyed coro1"); | |
70 if ( handle ) | |
71 handle.destroy(); | |
72 } | |
73 | |
74 struct suspend_never_prt { | |
75 bool await_ready() const noexcept { return true; } | |
76 void await_suspend(handle_type) const noexcept { PRINT ("susp-never-susp"); } | |
77 void await_resume() const noexcept { PRINT ("susp-never-resume");} | |
78 }; | |
79 | |
80 /* NOTE: this has a DTOR to test that pathway. */ | |
81 struct suspend_always_prt { | |
82 bool await_ready() const noexcept { return false; } | |
83 void await_suspend(handle_type) const noexcept { PRINT ("susp-always-susp"); } | |
84 void await_resume() const noexcept { PRINT ("susp-always-resume"); } | |
85 ~suspend_always_prt() { PRINT ("susp-always-DTOR"); } | |
86 }; | |
87 | |
88 }; | |
89 | |
90 int gX ; | |
91 | |
92 struct mycounter | |
93 { | |
94 mycounter () : v(0) { PRINT ("mycounter CTOR"); } | |
95 ~mycounter () { gX = 6174; PRINT ("mycounter DTOR"); } | |
96 int value () { return v; } | |
97 void incr () { v++; } | |
98 int v; | |
99 }; | |
100 | |
101 template <typename T> | |
102 looper<T> with_ctorable_state (std::vector<T> d) noexcept | |
103 { | |
104 std::vector<T> loc; | |
105 unsigned lim = d.size()-1; | |
106 mycounter c; | |
107 for (unsigned i = 0; i < lim ; ++i) | |
108 { | |
109 loc.push_back(d[i]); | |
110 c.incr(); | |
111 PRINTF ("f: about to yield value %d \n", i); | |
112 co_yield loc[i]; | |
113 } | |
114 loc.push_back(d[lim]); | |
115 | |
116 PRINT ("f: done"); | |
117 co_return loc[lim]; | |
118 } | |
119 | |
120 int main () | |
121 { | |
122 PRINT ("main: create looper"); | |
123 std::vector<std::string> input = {"first", "the", "quick", "reddish", "fox", "done" }; | |
124 auto f_coro = with_ctorable_state<std::string> (input); | |
125 | |
126 PRINT ("main: got looper - resuming (1)"); | |
127 if (f_coro.handle.done()) | |
128 abort(); | |
129 | |
130 f_coro.handle.resume(); | |
131 std::string s = f_coro.handle.promise().get_value(); | |
132 if ( s != "first" ) | |
133 abort (); | |
134 | |
135 PRINTF ("main: got : %s\n", s.c_str()); | |
136 unsigned check = 1; | |
137 do { | |
138 f_coro.handle.resume(); | |
139 s = f_coro.handle.promise().get_value(); | |
140 if (s != input[check++]) | |
141 abort (); | |
142 PRINTF ("main: got : %s\n", s.c_str()); | |
143 } while (!f_coro.handle.done()); | |
144 | |
145 if ( s != "done" ) | |
146 abort (); | |
147 | |
148 PRINT ("main: should be done"); | |
149 if (!f_coro.handle.done()) | |
150 { | |
151 PRINT ("main: apparently not done..."); | |
152 abort (); | |
153 } | |
154 | |
155 if (gX != 6174) | |
156 { | |
157 PRINT ("main: apparently we didn't run mycounter DTOR..."); | |
158 abort (); | |
159 } | |
160 PRINT ("main: returning"); | |
161 return 0; | |
162 } |