summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorAndrew Morrow <acm@10gen.com>2013-05-17 11:21:44 -0400
committerAndrew Morrow <acm@mongodb.com>2014-04-07 19:05:45 -0400
commit5f417e02075aa6c5ae80685927cd6fbca4ba6ca2 (patch)
tree7ee2ad9f778c1a6a326486e9bae28282b3e6aa2f /src/mongo
parent8784c38f824b9666dd3c68b80cd6069ef2970694 (diff)
downloadmongo-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.h14
-rw-r--r--src/mongo/base/status.h5
-rw-r--r--src/mongo/base/status_test.cpp119
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);