1 // { dg-do run { target c++17 } } 2 // 3 // Check if default return_void is insert at correct position. 4 #include <cassert> 5 #include "../coro.h" 6 7 class resumable { 8 public: 9 class promise_type; 10 using coro_handle = std::coroutine_handle<promise_type>; resumable(coro_handle handle)11 resumable(coro_handle handle) : handle_(handle) { assert(handle); } 12 resumable(resumable&) = delete; 13 resumable(resumable&&) = delete; resume()14 bool resume() { 15 if (!handle_.done()) 16 handle_.resume(); 17 return !handle_.done(); 18 } 19 int recent_val(); ~resumable()20 ~resumable() { handle_.destroy(); } 21 private: 22 coro_handle handle_; 23 }; 24 25 class resumable::promise_type { 26 public: 27 friend class resumable; 28 using coro_handle = std::coroutine_handle<promise_type>; get_return_object()29 auto get_return_object() { return coro_handle::from_promise(*this); } initial_suspend()30 auto initial_suspend() { return std::suspend_always(); } final_suspend()31 auto final_suspend() noexcept { return std::suspend_always(); } return_void()32 void return_void() { value_ = -1; } unhandled_exception()33 void unhandled_exception() {} 34 private: 35 int value_ = 0; 36 }; 37 recent_val()38int resumable::recent_val() {return handle_.promise().value_;} 39 foo(int n)40resumable foo(int n){ 41 co_await std::suspend_always(); 42 throw 1; 43 } 44 bar(int n)45int bar (int n) { 46 resumable res = foo(n); 47 while(res.resume()); 48 return res.recent_val(); 49 } 50 main()51int main() { 52 int res = bar(3); 53 assert(res == 0); 54 return 0; 55 } 56