blob: 0cf3c394dc2ba225991bf2207d9f1d77bb4189dd [file] [log] [blame]
// Check that we obey the extra rules for implicitly movable co_return
// objects [class.copy.elision]/3.
#include "coro.h"
#include <utility>
template <typename T>
struct coro1 {
struct promise_type;
using handle_type = coro::coroutine_handle<coro1::promise_type>;
handle_type handle;
coro1 () : handle(0) {}
coro1 (handle_type _handle)
: handle(_handle) { }
coro1 (const coro1 &) = delete; // no copying
coro1 (coro1 &&s) : handle(s.handle) { s.handle = nullptr; }
coro1 &operator = (coro1 &&s) {
handle = s.handle;
s.handle = nullptr;
return *this;
}
~coro1() {
if ( handle )
handle.destroy();
}
struct promise_type {
T value;
promise_type() {}
~promise_type() {}
auto get_return_object () { return handle_type::from_promise (*this);}
coro::suspend_always initial_suspend () const { return {}; }
coro::suspend_always final_suspend () const noexcept { return {}; }
void return_value(T&& v) noexcept { value = std::move(v); }
void return_value(const T&) noexcept = delete;
T get_value (void) { return value; }
void unhandled_exception() { }
};
};
struct MoveOnlyType
{
int value_;
explicit MoveOnlyType() noexcept : value_(0) {}
explicit MoveOnlyType(int value) noexcept : value_(value) {}
MoveOnlyType(MoveOnlyType&& other) noexcept
: value_(std::exchange(other.value_, -1)) {}
MoveOnlyType& operator=(MoveOnlyType&& other) noexcept {
value_ = std::exchange(other.value_, -1);
return *this;
}
~MoveOnlyType() { value_ = -2; }
};
bool b1, b2;
coro1<MoveOnlyType>
my_coro (MoveOnlyType p, MoveOnlyType &&r)
{
MoveOnlyType x{10};
if (b1)
co_return p;
else if (b2)
co_return r;
else
co_return x;
}