Commit 132623f0 authored by Kenton Varda's avatar Kenton Varda

`Maybe<T>(Maybe<T&>&&)` should do a copy, not a move.

`Maybe<T&>` does not own the `T` it points to. But, before this change, initializing a `Maybe<T>` from a `Maybe<T&>` would inadvertently perform a move, stealing the `T` away from its owner.
parent aa53106d
...@@ -50,6 +50,15 @@ struct Immovable { ...@@ -50,6 +50,15 @@ struct Immovable {
KJ_DISALLOW_COPY(Immovable); KJ_DISALLOW_COPY(Immovable);
}; };
struct CopyOrMove {
// Type that detects the difference between copy and move.
CopyOrMove(int i): i(i) {}
CopyOrMove(CopyOrMove&& other): i(other.i) { i = -1; }
CopyOrMove(const CopyOrMove&) = default;
int i;
};
TEST(Common, Maybe) { TEST(Common, Maybe) {
{ {
Maybe<int> m = 123; Maybe<int> m = 123;
...@@ -248,6 +257,15 @@ TEST(Common, Maybe) { ...@@ -248,6 +257,15 @@ TEST(Common, Maybe) {
m = nullptr; m = nullptr;
KJ_EXPECT(m == nullptr); KJ_EXPECT(m == nullptr);
} }
{
// Test that initializing Maybe<T> from Maybe<T&>&& does a copy, not a move.
CopyOrMove x(123);
Maybe<CopyOrMove&> m(x);
Maybe<CopyOrMove> m2 = kj::mv(m);
KJ_EXPECT(KJ_ASSERT_NONNULL(m).i == 123);
KJ_EXPECT(KJ_ASSERT_NONNULL(m2).i == 123);
}
} }
TEST(Common, MaybeConstness) { TEST(Common, MaybeConstness) {
......
...@@ -1121,6 +1121,12 @@ public: ...@@ -1121,6 +1121,12 @@ public:
} }
} }
template <typename U> template <typename U>
Maybe(Maybe<U&>&& other) {
KJ_IF_MAYBE(val, other) {
ptr.emplace(*val);
}
}
template <typename U>
Maybe(const Maybe<U>& other) { Maybe(const Maybe<U>& other) {
KJ_IF_MAYBE(val, other) { KJ_IF_MAYBE(val, other) {
ptr.emplace(*val); ptr.emplace(*val);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment