From 95b346c3ca6009a5d779533ae2d8d763ee9322d1 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Mon, 31 Oct 2016 18:24:17 +0800 Subject: [PATCH 1/2] Refactor GenericValue deep-clone constructor --- include/rapidjson/document.h | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 703c061..2da67a9 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -2419,11 +2419,28 @@ inline GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) { switch (rhs.GetType()) { - case kObjectType: - case kArrayType: { // perform deep copy via SAX Handler - GenericDocument d(&allocator); - rhs.Accept(d); - RawAssign(*d.stack_.template Pop(1)); + case kObjectType: { + SizeType count = rhs.data_.o.size; + Member* lm = reinterpret_cast(allocator.Malloc(count * sizeof(Member))); + const typename GenericValue::Member* rm = rhs.GetMembersPointer(); + for (SizeType i = 0; i < count; i++) { + new (&lm[i].name) GenericValue(rm[i].name, allocator); + new (&lm[i].value) GenericValue(rm[i].value, allocator); + } + data_.f.flags = kObjectFlag; + data_.o.size = data_.o.capacity = count; + SetMembersPointer(lm); + } + break; + case kArrayType: { + SizeType count = rhs.data_.a.size; + GenericValue* le = reinterpret_cast(allocator.Malloc(count * sizeof(GenericValue))); + const GenericValue* re = rhs.GetElementsPointer(); + for (SizeType i = 0; i < count; i++) + new (&le[i]) GenericValue(re[i], allocator); + data_.f.flags = kArrayFlag; + data_.a.size = data_.a.capacity = count; + SetElementsPointer(le); } break; case kStringType: From e07d0e94380b41d9cf45734a6af1c6d603b0fc71 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Mon, 31 Oct 2016 18:28:53 +0800 Subject: [PATCH 2/2] Move GenericValue deep-clone constructor into the class declaration. --- include/rapidjson/document.h | 89 +++++++++++++++++------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 2da67a9..895af88 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -617,8 +617,47 @@ public: \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). \see CopyFrom() */ - template< typename SourceAllocator > - GenericValue(const GenericValue& rhs, Allocator & allocator); + template + GenericValue(const GenericValue& rhs, Allocator& allocator) { + switch (rhs.GetType()) { + case kObjectType: { + SizeType count = rhs.data_.o.size; + Member* lm = reinterpret_cast(allocator.Malloc(count * sizeof(Member))); + const typename GenericValue::Member* rm = rhs.GetMembersPointer(); + for (SizeType i = 0; i < count; i++) { + new (&lm[i].name) GenericValue(rm[i].name, allocator); + new (&lm[i].value) GenericValue(rm[i].value, allocator); + } + data_.f.flags = kObjectFlag; + data_.o.size = data_.o.capacity = count; + SetMembersPointer(lm); + } + break; + case kArrayType: { + SizeType count = rhs.data_.a.size; + GenericValue* le = reinterpret_cast(allocator.Malloc(count * sizeof(GenericValue))); + const GenericValue* re = rhs.GetElementsPointer(); + for (SizeType i = 0; i < count; i++) + new (&le[i]) GenericValue(re[i], allocator); + data_.f.flags = kArrayFlag; + data_.a.size = data_.a.capacity = count; + SetElementsPointer(le); + } + break; + case kStringType: + if (rhs.data_.f.flags == kConstStringFlag) { + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + } + else + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + break; + default: + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + break; + } + } //! Constructor for boolean value. /*! \param b Boolean value @@ -2412,52 +2451,6 @@ private: //! GenericDocument with UTF8 encoding typedef GenericDocument > Document; -// defined here due to the dependency on GenericDocument -template -template -inline -GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) -{ - switch (rhs.GetType()) { - case kObjectType: { - SizeType count = rhs.data_.o.size; - Member* lm = reinterpret_cast(allocator.Malloc(count * sizeof(Member))); - const typename GenericValue::Member* rm = rhs.GetMembersPointer(); - for (SizeType i = 0; i < count; i++) { - new (&lm[i].name) GenericValue(rm[i].name, allocator); - new (&lm[i].value) GenericValue(rm[i].value, allocator); - } - data_.f.flags = kObjectFlag; - data_.o.size = data_.o.capacity = count; - SetMembersPointer(lm); - } - break; - case kArrayType: { - SizeType count = rhs.data_.a.size; - GenericValue* le = reinterpret_cast(allocator.Malloc(count * sizeof(GenericValue))); - const GenericValue* re = rhs.GetElementsPointer(); - for (SizeType i = 0; i < count; i++) - new (&le[i]) GenericValue(re[i], allocator); - data_.f.flags = kArrayFlag; - data_.a.size = data_.a.capacity = count; - SetElementsPointer(le); - } - break; - case kStringType: - if (rhs.data_.f.flags == kConstStringFlag) { - data_.f.flags = rhs.data_.f.flags; - data_ = *reinterpret_cast(&rhs.data_); - } else { - SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); - } - break; - default: - data_.f.flags = rhs.data_.f.flags; - data_ = *reinterpret_cast(&rhs.data_); - break; - } -} - //! Helper class for accessing Value of array type. /*! Instance of this helper class is obtained by \c GenericValue::GetArray().