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()66parse() 67 { 68 namespace B = A; 69 co_yield 1; 70 } 71 main()72int main() 73 { 74 auto gen = parse(); 75 gen.handle.resume (); /* init suspend. */ 76 if (gen.get() != 1) 77 abort (); 78 return 0; 79 } 80