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 }