1 // Check that we obey the extra rules for implicitly movable co_return
2 // objects [class.copy.elision]/3.
3 
4 #include "coro.h"
5 
6 #include  <utility>
7 
8 template <typename T>
9 struct coro1 {
10   struct promise_type;
11   using handle_type = coro::coroutine_handle<coro1::promise_type>;
12   handle_type handle;
coro1coro113   coro1 () : handle(0) {}
coro1coro114   coro1 (handle_type _handle)
15     : handle(_handle) { }
16   coro1 (const coro1 &) = delete; // no copying
coro1coro117   coro1 (coro1 &&s) : handle(s.handle) { s.handle = nullptr;  }
18   coro1 &operator = (coro1 &&s) {
19     handle = s.handle;
20     s.handle = nullptr;
21     return *this;
22   }
~coro1coro123   ~coro1() {
24     if ( handle )
25       handle.destroy();
26   }
27 
28   struct promise_type {
29   T value;
promise_typecoro1::promise_type30   promise_type() {}
~promise_typecoro1::promise_type31   ~promise_type() {}
32 
get_return_objectcoro1::promise_type33   auto get_return_object () { return handle_type::from_promise (*this);}
initial_suspendcoro1::promise_type34   coro::suspend_always initial_suspend () const { return {}; }
final_suspendcoro1::promise_type35   coro::suspend_always final_suspend () const noexcept {  return {}; }
36 
return_valuecoro1::promise_type37   void return_value(T&& v) noexcept { value = std::move(v); }
38 
get_valuecoro1::promise_type39   T get_value (void) { return value; }
unhandled_exceptioncoro1::promise_type40   void unhandled_exception() { }
41   };
42 };
43 
44 struct MoveOnlyType
45 {
46   int value_;
47 
MoveOnlyTypeMoveOnlyType48   explicit MoveOnlyType() noexcept : value_(0) {}
MoveOnlyTypeMoveOnlyType49   explicit MoveOnlyType(int value) noexcept : value_(value) {}
50 
MoveOnlyTypeMoveOnlyType51   MoveOnlyType(MoveOnlyType&& other) noexcept
52       : value_(std::exchange(other.value_, -1)) {}
53 
54   MoveOnlyType& operator=(MoveOnlyType&& other) noexcept {
55     value_ = std::exchange(other.value_, -1);
56     return *this;
57   }
58 
~MoveOnlyTypeMoveOnlyType59   ~MoveOnlyType() { value_ = -2; }
60 };
61 
62 coro1<MoveOnlyType>
my_coro()63 my_coro ()
64 {
65   MoveOnlyType x{10};
66   co_return x;
67 }
68