diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 889cdfa..5eeef9c 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -1803,6 +1803,22 @@ public: } #endif + //! Exchange the contents of this document with those of another. + /*! + \param other Another document. + \note Constant complexity. + \see GenericValue::Swap + */ + GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { + using std::swap; + ValueType::Swap(rhs); + stack_.Swap(rhs.stack_); + swap(allocator_, rhs.allocator_); + swap(ownAllocator_, rhs.ownAllocator_); + swap(parseResult_, rhs.parseResult_); + return *this; + } + //!@name Parse from stream //!@{ diff --git a/include/rapidjson/internal/stack.h b/include/rapidjson/internal/stack.h index bb31cc0..198c866 100644 --- a/include/rapidjson/internal/stack.h +++ b/include/rapidjson/internal/stack.h @@ -15,6 +15,8 @@ #ifndef RAPIDJSON_INTERNAL_STACK_H_ #define RAPIDJSON_INTERNAL_STACK_H_ +#include // std::swap + #include "../rapidjson.h" RAPIDJSON_NAMESPACE_BEGIN @@ -81,6 +83,17 @@ public: } #endif + void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { + using std::swap; + + swap(allocator_, rhs.allocator_); + swap(ownAllocator_, rhs.ownAllocator_); + swap(stack_, rhs.stack_); + swap(stackTop_, rhs.stackTop_); + swap(stackEnd_, rhs.stackEnd_); + swap(initialCapacity_, rhs.initialCapacity_); + } + void Clear() { stackTop_ = stack_; } void ShrinkToFit() { diff --git a/test/unittest/documenttest.cpp b/test/unittest/documenttest.cpp index 2ee6b10..3db7cd8 100644 --- a/test/unittest/documenttest.cpp +++ b/test/unittest/documenttest.cpp @@ -202,7 +202,8 @@ TEST(Document, Swap) { o.SetObject().AddMember("a", 1, a); // Swap between Document and Value - d1.Swap(o); + // d1.Swap(o); // doesn't compile + o.Swap(d1); EXPECT_TRUE(d1.IsObject()); EXPECT_TRUE(o.IsArray()); @@ -212,8 +213,19 @@ TEST(Document, Swap) { d1.Swap(d2); EXPECT_TRUE(d1.IsArray()); EXPECT_TRUE(d2.IsObject()); + EXPECT_EQ(&d2.GetAllocator(), &a); + + // reset value + Value().Swap(d1); + EXPECT_TRUE(d1.IsNull()); + + // reset document, including allocator + Document().Swap(d2); + EXPECT_TRUE(d2.IsNull()); + EXPECT_NE(&d2.GetAllocator(), &a); } + // This should be slow due to assignment in inner-loop. struct OutputStringStream : public std::ostringstream { typedef char Ch;