summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/value_internal.h
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2015-08-28 17:33:28 -0400
committerMathias Stearn <mathias@10gen.com>2015-09-18 14:00:07 -0400
commit041dc39c2b10296e6d175ca78ab1662903233637 (patch)
treec60f1e49e88d7403bb1d6c6c72a5cf38af782a49 /src/mongo/db/pipeline/value_internal.h
parentd38d401f6a11f20023aa2628723976fa993c16b6 (diff)
downloadmongo-041dc39c2b10296e6d175ca78ab1662903233637.tar.gz
SERVER-18520 Add move support to Document and Value
Diffstat (limited to 'src/mongo/db/pipeline/value_internal.h')
-rw-r--r--src/mongo/db/pipeline/value_internal.h36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/mongo/db/pipeline/value_internal.h b/src/mongo/db/pipeline/value_internal.h
index 21201a50c6e..e4aab6a072f 100644
--- a/src/mongo/db/pipeline/value_internal.h
+++ b/src/mongo/db/pipeline/value_internal.h
@@ -29,6 +29,7 @@
#pragma once
#include <algorithm>
+#include <boost/config.hpp>
#include <boost/intrusive_ptr.hpp>
#include "mongo/bson/bsonobj.h"
@@ -167,6 +168,11 @@ public:
memcpyed();
}
+ ValueStorage(ValueStorage&& rhs) BOOST_NOEXCEPT {
+ memcpy(this, &rhs, sizeof(*this));
+ rhs.zero(); // Reset rhs to the missing state. TODO consider only doing this if refCounter.
+ }
+
~ValueStorage() {
DEV verifyRefCountingIfShould();
if (refCounter)
@@ -174,8 +180,34 @@ public:
DEV memset(this, 0xee, sizeof(*this));
}
- ValueStorage& operator=(ValueStorage rhsCopy) {
- this->swap(rhsCopy);
+ ValueStorage& operator=(const ValueStorage& rhs) {
+ // This is designed to be effectively a no-op on self-assign, without needing an explicit
+ // check. This requires that rhs's refcount is incremented before ours is released, and that
+ // we use memmove rather than memcpy.
+ DEV rhs.verifyRefCountingIfShould();
+ if (rhs.refCounter)
+ intrusive_ptr_add_ref(rhs.genericRCPtr);
+
+ DEV verifyRefCountingIfShould();
+ if (refCounter)
+ intrusive_ptr_release(genericRCPtr);
+
+ memmove(this, &rhs, sizeof(*this));
+ return *this;
+ }
+
+ ValueStorage& operator=(ValueStorage&& rhs) BOOST_NOEXCEPT {
+#if defined(_MSC_VER) && _MSC_VER < 1900 // MSVC 2013 STL can emit self-move-assign.
+ if (&rhs == this)
+ return *this;
+#endif
+
+ DEV verifyRefCountingIfShould();
+ if (refCounter)
+ intrusive_ptr_release(genericRCPtr);
+
+ memmove(this, &rhs, sizeof(*this));
+ rhs.zero(); // Reset rhs to the missing state. TODO consider only doing this if refCounter.
return *this;
}