testsuite: don't declare printf in coro.h
[official-gcc.git] / gcc / testsuite / g++.dg / coroutines / torture / co-await-07-tmpl.C
blob8915786dd1efc3d2a898d9a2b28fda33ca5e9a6f
1 //  { dg-do run }
3 // Check that we correctly operate when the coroutine object is templated.
5 #include "../coro.h"
7 template <typename T> 
8 struct coro1 {
9   struct promise_type;
10   using handle_type = coro::coroutine_handle<coro1::promise_type>;
11   handle_type handle;
12   coro1 () : handle(0) {}
13   coro1 (handle_type _handle)
14     : handle(_handle) {
15         PRINT ("Created coro1 object from handle");
16   }
17   coro1 (const coro1 &) = delete; // no copying
18   coro1 (coro1 &&s) : handle(s.handle) {
19     s.handle = nullptr;
20     PRINT ("Moved coro1");
21   }
22   coro1 &operator = (coro1 &&s) {
23     handle = s.handle;
24     s.handle = nullptr;
25     return *this;
26   }
27   ~coro1() {
28     PRINT ("Destroyed coro1");
29     if ( handle )
30       handle.destroy();
31   }
33   struct suspend_never_prt {
34     ~suspend_never_prt() {}
35     bool await_ready() const noexcept { return true; }
36     void await_suspend(handle_type h) const noexcept { PRINT ("susp-never-susp");}
37     void await_resume() const noexcept {PRINT ("susp-never-resume");}
38   };
40   struct  suspend_always_prt {
41     T x;
42     bool await_ready() const noexcept { return false; }
43     void await_suspend(handle_type) const noexcept { PRINT ("susp-always-susp");}
44     void await_resume() const noexcept {PRINT ("susp-always-resume");}
45   };
47   /* This returns the int it was constructed with.  */
48   struct suspend_always_intprt {
49     T x;
50     suspend_always_intprt() : x((T)5) { PRINT ("suspend_always_intprt def ctor"); }
51     suspend_always_intprt(T _x) : x(_x)
52       { PRINTF ("suspend_always_intprt ctor with %ld\n", (long)x); }
53     ~suspend_always_intprt() {}
54     bool await_ready() const noexcept { return false; }
55     void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("susp-always-susp-int");}
56     int await_resume() const noexcept { PRINT ("susp-always-resume-int"); return x;}
57   };
59   struct promise_type {
60   T value;
61   promise_type()  { PRINT ("Created Promise"); }
62   ~promise_type() { PRINT ("Destroyed Promise"); }
64   coro1 get_return_object() {
65     PRINT ("get_return_object: from handle from promise");
66     return coro1 (handle_type::from_promise (*this));
67   }
69   auto initial_suspend() {
70     PRINT ("get initial_suspend ");
71     return suspend_never_prt{};
72   }
74   auto final_suspend() noexcept {
75     PRINT ("get final_suspend");
76     return suspend_always_prt{};
77   }
79   void return_value (int v) {
80     PRINTF ("return_value () %ld\n", (long) v);
81     value = v;
82   }
84   auto await_transform (T v) {
85     PRINTF ("await_transform a T () %ld\n", (long)v);
86     return suspend_always_intprt (v);
87   }
89   T get_value () { return value; }
90   void unhandled_exception() { PRINT ("** unhandled exception"); }
91   };
94 /* Valued with an await_transform.  */
95 int gX = 2;
97 template <typename T> 
98 coro1<T> f ()
100   for (int i = 0; i < 4; ++i)
101     {
102       gX += co_await 10;
103     }
104   co_return gX;
107 int main ()
109   PRINT ("main: create coro1");
110   auto f_coro = f<int>();
111   
112   PRINT ("main: got coro1 - checking gX");
113   if (gX != 2)
114     {
115       PRINTF ("main: gX is wrong : %d, should be 2\n", gX);
116       abort ();
117     }
118   PRINT ("main: gX OK -- looping");
119   do {
120     f_coro.handle.resume();
121   } while (!f_coro.handle.done());
123   int y = f_coro.handle.promise().get_value();
125   if (y != 42)
126     {
127       PRINTF ("main: y is wrong : %d, should be 42\n", y);
128       abort ();
129     }
130   PRINT ("main: done");
131   return 0;