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()38 int resumable::recent_val() {return handle_.promise().value_;}
39 
foo(int n)40 resumable foo(int n){
41   co_await std::suspend_always();
42   throw 1;
43 }
44 
bar(int n)45 int bar (int n) {
46   resumable res = foo(n);
47   while(res.resume());
48   return res.recent_val();
49 }
50 
main()51 int main() {
52   int res = bar(3);
53   assert(res == 0);
54   return 0;
55 }
56