diff options
author | Andrew Morrow <acm@10gen.com> | 2013-05-17 11:21:44 -0400 |
---|---|---|
committer | Andrew Morrow <acm@mongodb.com> | 2014-04-07 19:05:45 -0400 |
commit | 5f417e02075aa6c5ae80685927cd6fbca4ba6ca2 (patch) | |
tree | 7ee2ad9f778c1a6a326486e9bae28282b3e6aa2f /src/mongo | |
parent | 8784c38f824b9666dd3c68b80cd6069ef2970694 (diff) | |
download | mongo-5f417e02075aa6c5ae80685927cd6fbca4ba6ca2.tar.gz |
SERVER-13470 Give Status move semantics in C++11 mode
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/base/status-inl.h | 14 | ||||
-rw-r--r-- | src/mongo/base/status.h | 5 | ||||
-rw-r--r-- | src/mongo/base/status_test.cpp | 119 |
3 files changed, 138 insertions, 0 deletions
diff --git a/src/mongo/base/status-inl.h b/src/mongo/base/status-inl.h index add962e2369..1e75e3bbd68 100644 --- a/src/mongo/base/status-inl.h +++ b/src/mongo/base/status-inl.h @@ -33,6 +33,20 @@ namespace mongo { return *this; } +#if __cplusplus >= 201103L + inline Status::Status(Status&& other) noexcept + : _error(other._error) { + other._error = nullptr; + } + + inline Status& Status::operator=(Status&& other) noexcept { + unref(_error); + _error = other._error; + other._error = nullptr; + return *this; + } +#endif // __cplusplus >= 201103L + inline Status::~Status() { unref(_error); } diff --git a/src/mongo/base/status.h b/src/mongo/base/status.h index ad301f8b008..d897705c9e3 100644 --- a/src/mongo/base/status.h +++ b/src/mongo/base/status.h @@ -63,6 +63,11 @@ namespace mongo { inline Status(const Status& other); inline Status& operator=(const Status& other); +#if __cplusplus >= 201103L + inline Status(Status&& other) noexcept; + inline Status& operator=(Status&& other) noexcept; +#endif // __cplusplus >= 201103L + inline ~Status(); /** diff --git a/src/mongo/base/status_test.cpp b/src/mongo/base/status_test.cpp index abda898c7f5..28d48c26b28 100644 --- a/src/mongo/base/status_test.cpp +++ b/src/mongo/base/status_test.cpp @@ -67,6 +67,125 @@ namespace { ASSERT_EQUALS(orig.refCount(), 2U); } +#if __cplusplus >= 201103L + TEST(Cloning, MoveCopyOK) { + Status orig = Status::OK(); + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + Status dest(std::move(orig)); + + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + ASSERT_TRUE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 0U); + } + + TEST(Cloning, MoveCopyError) { + Status orig(ErrorCodes::MaxError, "error"); + ASSERT_FALSE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 1U); + + Status dest(std::move(orig)); + + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + ASSERT_FALSE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 1U); + ASSERT_EQUALS(dest.code(), ErrorCodes::MaxError); + ASSERT_EQUALS(dest.reason(), "error"); + } + + TEST(Cloning, MoveAssignOKToOK) { + Status orig = Status::OK(); + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + Status dest = Status::OK(); + ASSERT_TRUE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 0U); + + dest = std::move(orig); + + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + ASSERT_TRUE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 0U); + } + + TEST(Cloning, MoveAssignErrorToError) { + Status orig = Status(ErrorCodes::MaxError, "error"); + ASSERT_FALSE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 1U); + ASSERT_EQUALS(orig.code(), ErrorCodes::MaxError); + ASSERT_EQUALS(orig.reason(), "error"); + + Status dest = Status(ErrorCodes::InternalError, "error2"); + ASSERT_FALSE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 1U); + ASSERT_EQUALS(dest.code(), ErrorCodes::InternalError); + ASSERT_EQUALS(dest.reason(), "error2"); + + dest = std::move(orig); + + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + ASSERT_FALSE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 1U); + ASSERT_EQUALS(dest.code(), ErrorCodes::MaxError); + ASSERT_EQUALS(dest.reason(), "error"); + } + + TEST(Cloning, MoveAssignErrorToOK) { + Status orig = Status(ErrorCodes::MaxError, "error"); + ASSERT_FALSE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 1U); + ASSERT_EQUALS(orig.code(), ErrorCodes::MaxError); + ASSERT_EQUALS(orig.reason(), "error"); + + Status dest = Status::OK(); + ASSERT_TRUE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 0U); + + dest = std::move(orig); + + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + ASSERT_FALSE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 1U); + ASSERT_EQUALS(dest.code(), ErrorCodes::MaxError); + ASSERT_EQUALS(dest.reason(), "error"); + } + + TEST(Cloning, MoveAssignOKToError) { + Status orig = Status::OK(); + ASSERT_TRUE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 0U); + + Status dest = Status(ErrorCodes::MaxError, "error"); + ASSERT_FALSE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 1U); + ASSERT_EQUALS(dest.code(), ErrorCodes::MaxError); + ASSERT_EQUALS(dest.reason(), "error"); + + orig = std::move(dest); + + ASSERT_FALSE(orig.isOK()); + ASSERT_EQUALS(orig.refCount(), 1U); + ASSERT_EQUALS(orig.code(), ErrorCodes::MaxError); + ASSERT_EQUALS(orig.reason(), "error"); + + ASSERT_TRUE(dest.isOK()); + ASSERT_EQUALS(dest.refCount(), 0U); + } + +#endif // __cplusplus >= 201103L + TEST(Cloning, OKIsNotRefCounted) { ASSERT_EQUALS(Status::OK().refCount(), 0U); |