Unverified Commit 9f31cd49 authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #747 from capnproto/overload-operatoreq

Overload Maybe::operator=() to match all copy constructors.
parents a00ccd91 f693e2e5
......@@ -45,6 +45,11 @@ struct ImplicitToInt {
}
};
struct Immovable {
Immovable() = default;
KJ_DISALLOW_COPY(Immovable);
};
TEST(Common, Maybe) {
{
Maybe<int> m = 123;
......@@ -63,6 +68,23 @@ TEST(Common, Maybe) {
EXPECT_EQ(123, m.orDefault(456));
}
{
Maybe<int> m = 0;
EXPECT_FALSE(m == nullptr);
EXPECT_TRUE(m != nullptr);
KJ_IF_MAYBE(v, m) {
EXPECT_EQ(0, *v);
} else {
ADD_FAILURE();
}
KJ_IF_MAYBE(v, mv(m)) {
EXPECT_EQ(0, *v);
} else {
ADD_FAILURE();
}
EXPECT_EQ(0, m.orDefault(456));
}
{
Maybe<int> m = nullptr;
EXPECT_TRUE(m == nullptr);
......@@ -216,6 +238,16 @@ TEST(Common, Maybe) {
ADD_FAILURE();
}
}
{
// Test usage of immovable types.
Maybe<Immovable> m;
KJ_EXPECT(m == nullptr);
m.emplace();
KJ_EXPECT(m != nullptr);
m = nullptr;
KJ_EXPECT(m == nullptr);
}
}
TEST(Common, MaybeConstness) {
......
......@@ -870,7 +870,7 @@ class NullableValue {
// boolean flag indicating nullness.
public:
inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance<T&&>())))
inline NullableValue(NullableValue&& other)
: isSet(other.isSet) {
if (isSet) {
ctor(value, kj::mv(other.value));
......@@ -922,8 +922,8 @@ public:
return value;
}
inline NullableValue() noexcept: isSet(false) {}
inline NullableValue(T&& t) noexcept(noexcept(T(instance<T&&>())))
inline NullableValue(): isSet(false) {}
inline NullableValue(T&& t)
: isSet(true) {
ctor(value, kj::mv(t));
}
......@@ -940,7 +940,7 @@ public:
if (isSet) ctor(value, *t);
}
template <typename U>
inline NullableValue(NullableValue<U>&& other) noexcept(noexcept(T(instance<U&&>())))
inline NullableValue(NullableValue<U>&& other)
: isSet(other.isSet) {
if (isSet) {
ctor(value, kj::mv(other.value));
......@@ -1007,6 +1007,52 @@ public:
return *this;
}
inline NullableValue& operator=(T&& other) { emplace(kj::mv(other)); return *this; }
inline NullableValue& operator=(T& other) { emplace(other); return *this; }
inline NullableValue& operator=(const T& other) { emplace(other); return *this; }
inline NullableValue& operator=(const T* other) {
if (other == nullptr) {
*this = nullptr;
} else {
emplace(*other);
}
return *this;
}
template <typename U>
inline NullableValue& operator=(NullableValue<U>&& other) {
if (other.isSet) {
emplace(kj::mv(other.value));
} else {
*this = nullptr;
}
return *this;
}
template <typename U>
inline NullableValue& operator=(const NullableValue<U>& other) {
if (other.isSet) {
emplace(other.value);
} else {
*this = nullptr;
}
return *this;
}
template <typename U>
inline NullableValue& operator=(const NullableValue<U&>& other) {
if (other.isSet) {
emplace(other.value);
} else {
*this = nullptr;
}
return *this;
}
inline NullableValue& operator=(decltype(nullptr)) {
if (isSet) {
isSet = false;
dtor(value);
}
return *this;
}
inline bool operator==(decltype(nullptr)) const { return !isSet; }
inline bool operator!=(decltype(nullptr)) const { return isSet; }
......@@ -1060,16 +1106,16 @@ class Maybe {
public:
Maybe(): ptr(nullptr) {}
Maybe(T&& t) noexcept(noexcept(T(instance<T&&>()))): ptr(kj::mv(t)) {}
Maybe(T&& t): ptr(kj::mv(t)) {}
Maybe(T& t): ptr(t) {}
Maybe(const T& t): ptr(t) {}
Maybe(const T* t) noexcept: ptr(t) {}
Maybe(Maybe&& other) noexcept(noexcept(T(instance<T&&>()))): ptr(kj::mv(other.ptr)) {}
Maybe(const T* t): ptr(t) {}
Maybe(Maybe&& other): ptr(kj::mv(other.ptr)) {}
Maybe(const Maybe& other): ptr(other.ptr) {}
Maybe(Maybe& other): ptr(other.ptr) {}
template <typename U>
Maybe(Maybe<U>&& other) noexcept(noexcept(T(instance<U&&>()))) {
Maybe(Maybe<U>&& other) {
KJ_IF_MAYBE(val, kj::mv(other)) {
ptr.emplace(kj::mv(*val));
}
......@@ -1081,7 +1127,7 @@ public:
}
}
Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {}
Maybe(decltype(nullptr)): ptr(nullptr) {}
template <typename... Params>
inline T& emplace(Params&&... params) {
......@@ -1092,10 +1138,36 @@ public:
return ptr.emplace(kj::fwd<Params>(params)...);
}
inline Maybe& operator=(T&& other) { ptr = kj::mv(other); return *this; }
inline Maybe& operator=(T& other) { ptr = other; return *this; }
inline Maybe& operator=(const T& other) { ptr = other; return *this; }
inline Maybe& operator=(const T* other) { ptr = other; return *this; }
inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; }
inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; }
inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; }
template <typename U>
Maybe& operator=(Maybe<U>&& other) {
KJ_IF_MAYBE(val, kj::mv(other)) {
ptr.emplace(kj::mv(*val));
} else {
ptr = nullptr;
}
return *this;
}
template <typename U>
Maybe& operator=(const Maybe<U>& other) {
KJ_IF_MAYBE(val, other) {
ptr.emplace(*val);
} else {
ptr = nullptr;
}
return *this;
}
inline Maybe& operator=(decltype(nullptr)) { ptr = nullptr; return *this; }
inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; }
inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; }
......@@ -1180,22 +1252,22 @@ private:
template <typename T>
class Maybe<T&>: public DisallowConstCopyIfNotConst<T> {
public:
Maybe() noexcept: ptr(nullptr) {}
Maybe(T& t) noexcept: ptr(&t) {}
Maybe(T* t) noexcept: ptr(t) {}
Maybe(): ptr(nullptr) {}
Maybe(T& t): ptr(&t) {}
Maybe(T* t): ptr(t) {}
template <typename U>
inline Maybe(Maybe<U&>& other) noexcept: ptr(other.ptr) {}
inline Maybe(Maybe<U&>& other): ptr(other.ptr) {}
template <typename U>
inline Maybe(const Maybe<U&>& other) noexcept: ptr(const_cast<const U*>(other.ptr)) {}
inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {}
inline Maybe(const Maybe<U&>& other): ptr(const_cast<const U*>(other.ptr)) {}
inline Maybe(decltype(nullptr)): ptr(nullptr) {}
inline Maybe& operator=(T& other) noexcept { ptr = &other; return *this; }
inline Maybe& operator=(T* other) noexcept { ptr = other; return *this; }
inline Maybe& operator=(T& other) { ptr = &other; return *this; }
inline Maybe& operator=(T* other) { ptr = other; return *this; }
template <typename U>
inline Maybe& operator=(Maybe<U&>& other) noexcept { ptr = other.ptr; return *this; }
inline Maybe& operator=(Maybe<U&>& other) { ptr = other.ptr; return *this; }
template <typename U>
inline Maybe& operator=(const Maybe<const U&>& other) noexcept { ptr = other.ptr; return *this; }
inline Maybe& operator=(const Maybe<const U&>& other) { ptr = other.ptr; return *this; }
inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; }
inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; }
......
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