Merge pull request #376 from pah/feature/document-swap
add GenericDocument<>::Swap with std::swap() support
This commit is contained in:
commit
823b731896
@ -660,6 +660,20 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! free-standing swap function helper
|
||||||
|
/*!
|
||||||
|
Helper function to enable support for common swap implementation pattern based on \c std::swap:
|
||||||
|
\code
|
||||||
|
void swap(MyClass& a, MyClass& b) {
|
||||||
|
using std::swap;
|
||||||
|
swap(a.value, b.value);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\see Swap()
|
||||||
|
*/
|
||||||
|
friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
|
||||||
|
|
||||||
//! Prepare Value for move semantics
|
//! Prepare Value for move semantics
|
||||||
/*! \return *this */
|
/*! \return *this */
|
||||||
GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
|
GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
|
||||||
@ -1818,6 +1832,35 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#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 {
|
||||||
|
ValueType::Swap(rhs);
|
||||||
|
stack_.Swap(rhs.stack_);
|
||||||
|
internal::Swap(allocator_, rhs.allocator_);
|
||||||
|
internal::Swap(ownAllocator_, rhs.ownAllocator_);
|
||||||
|
internal::Swap(parseResult_, rhs.parseResult_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! free-standing swap function helper
|
||||||
|
/*!
|
||||||
|
Helper function to enable support for common swap implementation pattern based on \c std::swap:
|
||||||
|
\code
|
||||||
|
void swap(MyClass& a, MyClass& b) {
|
||||||
|
using std::swap;
|
||||||
|
swap(a.doc, b.doc);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\see Swap()
|
||||||
|
*/
|
||||||
|
friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
|
||||||
|
|
||||||
//!@name Parse from stream
|
//!@name Parse from stream
|
||||||
//!@{
|
//!@{
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define RAPIDJSON_INTERNAL_STACK_H_
|
#define RAPIDJSON_INTERNAL_STACK_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
#include "swap.h"
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -81,6 +82,15 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
|
internal::Swap(allocator_, rhs.allocator_);
|
||||||
|
internal::Swap(ownAllocator_, rhs.ownAllocator_);
|
||||||
|
internal::Swap(stack_, rhs.stack_);
|
||||||
|
internal::Swap(stackTop_, rhs.stackTop_);
|
||||||
|
internal::Swap(stackEnd_, rhs.stackEnd_);
|
||||||
|
internal::Swap(initialCapacity_, rhs.initialCapacity_);
|
||||||
|
}
|
||||||
|
|
||||||
void Clear() { stackTop_ = stack_; }
|
void Clear() { stackTop_ = stack_; }
|
||||||
|
|
||||||
void ShrinkToFit() {
|
void ShrinkToFit() {
|
||||||
|
37
include/rapidjson/internal/swap.h
Normal file
37
include/rapidjson/internal/swap.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://opensource.org/licenses/MIT
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_INTERNAL_SWAP_H_
|
||||||
|
#define RAPIDJSON_INTERNAL_SWAP_H_
|
||||||
|
|
||||||
|
#include "../rapidjson.h"
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
//! Custom swap() to avoid dependency on C++ <algorith> header
|
||||||
|
/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
|
||||||
|
\note This has the same semantics as std::swap().
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
|
||||||
|
T tmp = a;
|
||||||
|
a = b;
|
||||||
|
b = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_INTERNAL_SWAP_H_
|
@ -19,6 +19,7 @@
|
|||||||
#include "rapidjson/encodedstream.h"
|
#include "rapidjson/encodedstream.h"
|
||||||
#include "rapidjson/stringbuffer.h"
|
#include "rapidjson/stringbuffer.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
|
|
||||||
@ -202,7 +203,8 @@ TEST(Document, Swap) {
|
|||||||
o.SetObject().AddMember("a", 1, a);
|
o.SetObject().AddMember("a", 1, a);
|
||||||
|
|
||||||
// Swap between Document and Value
|
// Swap between Document and Value
|
||||||
d1.Swap(o);
|
// d1.Swap(o); // doesn't compile
|
||||||
|
o.Swap(d1);
|
||||||
EXPECT_TRUE(d1.IsObject());
|
EXPECT_TRUE(d1.IsObject());
|
||||||
EXPECT_TRUE(o.IsArray());
|
EXPECT_TRUE(o.IsArray());
|
||||||
|
|
||||||
@ -212,8 +214,30 @@ TEST(Document, Swap) {
|
|||||||
d1.Swap(d2);
|
d1.Swap(d2);
|
||||||
EXPECT_TRUE(d1.IsArray());
|
EXPECT_TRUE(d1.IsArray());
|
||||||
EXPECT_TRUE(d2.IsObject());
|
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);
|
||||||
|
|
||||||
|
// testing std::swap compatibility
|
||||||
|
d1.SetBool(true);
|
||||||
|
using std::swap;
|
||||||
|
swap(d1, d2);
|
||||||
|
EXPECT_TRUE(d1.IsNull());
|
||||||
|
EXPECT_TRUE(d2.IsTrue());
|
||||||
|
|
||||||
|
swap(o, d2);
|
||||||
|
EXPECT_TRUE(o.IsTrue());
|
||||||
|
EXPECT_TRUE(d2.IsArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This should be slow due to assignment in inner-loop.
|
// This should be slow due to assignment in inner-loop.
|
||||||
struct OutputStringStream : public std::ostringstream {
|
struct OutputStringStream : public std::ostringstream {
|
||||||
typedef char Ch;
|
typedef char Ch;
|
||||||
|
@ -272,6 +272,12 @@ TEST(Value, Swap) {
|
|||||||
EXPECT_TRUE(v1.IsObject());
|
EXPECT_TRUE(v1.IsObject());
|
||||||
EXPECT_TRUE(v2.IsInt());
|
EXPECT_TRUE(v2.IsInt());
|
||||||
EXPECT_EQ(1234, v2.GetInt());
|
EXPECT_EQ(1234, v2.GetInt());
|
||||||
|
|
||||||
|
// testing std::swap compatibility
|
||||||
|
using std::swap;
|
||||||
|
swap(v1, v2);
|
||||||
|
EXPECT_TRUE(v1.IsInt());
|
||||||
|
EXPECT_TRUE(v2.IsObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Value, Null) {
|
TEST(Value, Null) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user