1 //  { dg-do run }
2 
3 #if __has_include(<coroutine>)
4 #include <coroutine>
5 #else
6 #include <experimental/coroutine>
7 namespace std {
8     using namespace std::experimental;
9 }
10 #endif
11 #include <cstdlib>
12 
13 template <typename T>
14 struct generator{
15     struct promise_type;
16     using coro_handle = std::coroutine_handle<promise_type>;
17 
18     struct promise_type{
yield_valuegenerator::promise_type19         std::suspend_always yield_value (T value){
20             value_ = value;
21             return {};
22         }
initial_suspendgenerator::promise_type23         std::suspend_always initial_suspend (){
24             return {};
25         }
final_suspendgenerator::promise_type26         std::suspend_always final_suspend (){
27             return {};
28         }
29 
return_voidgenerator::promise_type30         std::suspend_never return_void()
31         {
32             return {};
33         }
get_return_objectgenerator::promise_type34         generator get_return_object () {
35             return {coro_handle::from_promise(*this)};
36         }
unhandled_exceptiongenerator::promise_type37         void unhandled_exception () {
38             return;
39         }
40         T value_;
41     };
42     coro_handle handle;
generatorgenerator43     generator(coro_handle h)
44         :handle(h)
45     {}
~generatorgenerator46     ~generator(){
47         if(handle)
48             handle.destroy();
49     }
50 
resumegenerator51     bool resume(){
52         if(not handle.done())
53             handle.resume();
54         return not handle.done();
55     };
56 
getgenerator57     T get () {
58         return handle.promise().value_;
59     }
60 };
61 namespace A
62 {
63 }
64 
65 generator<int>
parse()66 parse()
67 {
68     namespace B = A;
69     co_yield 1;
70 }
71 
main()72 int main()
73 {
74     auto gen = parse();
75     gen.handle.resume (); /* init suspend. */
76     if (gen.get() != 1)
77       abort ();
78   return 0;
79 }
80