From 26491cff1eabf3baf355498f3bcdda21aa0bf241 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Sun, 23 Nov 2014 19:03:06 +0800 Subject: [PATCH 1/3] Fix additional compilation errors in unit tests for VC --- test/unittest/stringbuffertest.cpp | 150 +++++++++++++++-------------- 1 file changed, 78 insertions(+), 72 deletions(-) diff --git a/test/unittest/stringbuffertest.cpp b/test/unittest/stringbuffertest.cpp index b808ac5..24a29cb 100644 --- a/test/unittest/stringbuffertest.cpp +++ b/test/unittest/stringbuffertest.cpp @@ -25,48 +25,48 @@ using namespace rapidjson; TEST(StringBuffer, InitialSize) { - StringBuffer buffer; - EXPECT_EQ(0u, buffer.GetSize()); - EXPECT_STREQ("", buffer.GetString()); + StringBuffer buffer; + EXPECT_EQ(0u, buffer.GetSize()); + EXPECT_STREQ("", buffer.GetString()); } TEST(StringBuffer, Put) { - StringBuffer buffer; - buffer.Put('A'); + StringBuffer buffer; + buffer.Put('A'); - EXPECT_EQ(1u, buffer.GetSize()); - EXPECT_STREQ("A", buffer.GetString()); + EXPECT_EQ(1u, buffer.GetSize()); + EXPECT_STREQ("A", buffer.GetString()); } TEST(StringBuffer, Clear) { - StringBuffer buffer; - buffer.Put('A'); - buffer.Put('B'); - buffer.Put('C'); - buffer.Clear(); + StringBuffer buffer; + buffer.Put('A'); + buffer.Put('B'); + buffer.Put('C'); + buffer.Clear(); - EXPECT_EQ(0u, buffer.GetSize()); - EXPECT_STREQ("", buffer.GetString()); + EXPECT_EQ(0u, buffer.GetSize()); + EXPECT_STREQ("", buffer.GetString()); } TEST(StringBuffer, Push) { - StringBuffer buffer; - buffer.Push(5); + StringBuffer buffer; + buffer.Push(5); - EXPECT_EQ(5u, buffer.GetSize()); + EXPECT_EQ(5u, buffer.GetSize()); } TEST(StringBuffer, Pop) { - StringBuffer buffer; - buffer.Put('A'); - buffer.Put('B'); - buffer.Put('C'); - buffer.Put('D'); - buffer.Put('E'); - buffer.Pop(3); + StringBuffer buffer; + buffer.Put('A'); + buffer.Put('B'); + buffer.Put('C'); + buffer.Put('D'); + buffer.Put('E'); + buffer.Pop(3); - EXPECT_EQ(2u, buffer.GetSize()); - EXPECT_STREQ("AB", buffer.GetString()); + EXPECT_EQ(2u, buffer.GetSize()); + EXPECT_STREQ("AB", buffer.GetString()); } #if RAPIDJSON_HAS_CXX11_RVALUE_REFS @@ -74,67 +74,73 @@ TEST(StringBuffer, Pop) { #include TEST(StringBuffer, Traits) { - static_assert( std::is_constructible::value, ""); - static_assert( std::is_default_constructible::value, ""); - static_assert(!std::is_copy_constructible::value, ""); - static_assert( std::is_move_constructible::value, ""); + static_assert( std::is_constructible::value, ""); + static_assert( std::is_default_constructible::value, ""); +#ifndef _MSC_VER + static_assert(!std::is_copy_constructible::value, ""); +#endif + static_assert( std::is_move_constructible::value, ""); - static_assert(!std::is_nothrow_constructible::value, ""); - static_assert(!std::is_nothrow_default_constructible::value, ""); - static_assert(!std::is_nothrow_copy_constructible::value, ""); - static_assert(!std::is_nothrow_move_constructible::value, ""); + static_assert(!std::is_nothrow_constructible::value, ""); + static_assert(!std::is_nothrow_default_constructible::value, ""); + static_assert(!std::is_nothrow_copy_constructible::value, ""); + static_assert(!std::is_nothrow_move_constructible::value, ""); - static_assert( std::is_assignable::value, ""); - static_assert(!std::is_copy_assignable::value, ""); - static_assert( std::is_move_assignable::value, ""); + static_assert( std::is_assignable::value, ""); +#ifndef _MSC_VER + static_assert(!std::is_copy_assignable::value, ""); +#endif + static_assert( std::is_move_assignable::value, ""); - static_assert(!std::is_nothrow_assignable::value, ""); - static_assert(!std::is_nothrow_copy_assignable::value, ""); - static_assert(!std::is_nothrow_move_assignable::value, ""); + static_assert(!std::is_nothrow_assignable::value, ""); + static_assert(!std::is_nothrow_copy_assignable::value, ""); + static_assert(!std::is_nothrow_move_assignable::value, ""); - static_assert( std::is_destructible::value, ""); - static_assert( std::is_nothrow_destructible::value, ""); + static_assert( std::is_destructible::value, ""); +#ifndef _MSC_VER + static_assert(std::is_nothrow_destructible::value, ""); +#endif } TEST(StringBuffer, MoveConstructor) { - StringBuffer x; - x.Put('A'); - x.Put('B'); - x.Put('C'); - x.Put('D'); + StringBuffer x; + x.Put('A'); + x.Put('B'); + x.Put('C'); + x.Put('D'); - EXPECT_EQ(4u, x.GetSize()); - EXPECT_STREQ("ABCD", x.GetString()); + EXPECT_EQ(4u, x.GetSize()); + EXPECT_STREQ("ABCD", x.GetString()); - // StringBuffer y(x); // does not compile (!is_copy_constructible) - StringBuffer y(std::move(x)); - EXPECT_EQ(0u, x.GetSize()); - EXPECT_EQ(4u, y.GetSize()); - EXPECT_STREQ("ABCD", y.GetString()); + // StringBuffer y(x); // does not compile (!is_copy_constructible) + StringBuffer y(std::move(x)); + EXPECT_EQ(0u, x.GetSize()); + EXPECT_EQ(4u, y.GetSize()); + EXPECT_STREQ("ABCD", y.GetString()); - // StringBuffer z = y; // does not compile (!is_copy_assignable) - StringBuffer z = std::move(y); - EXPECT_EQ(0u, y.GetSize()); - EXPECT_EQ(4u, z.GetSize()); - EXPECT_STREQ("ABCD", z.GetString()); + // StringBuffer z = y; // does not compile (!is_copy_assignable) + StringBuffer z = std::move(y); + EXPECT_EQ(0u, y.GetSize()); + EXPECT_EQ(4u, z.GetSize()); + EXPECT_STREQ("ABCD", z.GetString()); } TEST(StringBuffer, MoveAssignment) { - StringBuffer x; - x.Put('A'); - x.Put('B'); - x.Put('C'); - x.Put('D'); + StringBuffer x; + x.Put('A'); + x.Put('B'); + x.Put('C'); + x.Put('D'); - EXPECT_EQ(4u, x.GetSize()); - EXPECT_STREQ("ABCD", x.GetString()); + EXPECT_EQ(4u, x.GetSize()); + EXPECT_STREQ("ABCD", x.GetString()); - StringBuffer y; - // y = x; // does not compile (!is_copy_assignable) - y = std::move(x); - EXPECT_EQ(0u, x.GetSize()); - EXPECT_EQ(4u, y.GetSize()); - EXPECT_STREQ("ABCD", y.GetString()); + StringBuffer y; + // y = x; // does not compile (!is_copy_assignable) + y = std::move(x); + EXPECT_EQ(0u, x.GetSize()); + EXPECT_EQ(4u, y.GetSize()); + EXPECT_STREQ("ABCD", y.GetString()); } #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS From 5a96c1f93e01f021d89536452a2357cdd54c4f3d Mon Sep 17 00:00:00 2001 From: Anton Indrawan Date: Sun, 23 Nov 2014 21:03:57 +0100 Subject: [PATCH 2/3] Compile all examples with the Dinkum C++ of QNX 6.6 QCC -Wall -Wextra -Vgcc_ntoarmv7le -I../include --- example/tutorial/tutorial.cpp | 1 + include/rapidjson/filereadstream.h | 4 ++-- include/rapidjson/filestream.h | 4 ++-- include/rapidjson/filewritestream.h | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/example/tutorial/tutorial.cpp b/example/tutorial/tutorial.cpp index b72db00..57f94a5 100644 --- a/example/tutorial/tutorial.cpp +++ b/example/tutorial/tutorial.cpp @@ -7,6 +7,7 @@ #include using namespace rapidjson; +using namespace std; int main(int, char*[]) { //////////////////////////////////////////////////////////////////////////// diff --git a/include/rapidjson/filereadstream.h b/include/rapidjson/filereadstream.h index ea46dac..4ff4ab9 100644 --- a/include/rapidjson/filereadstream.h +++ b/include/rapidjson/filereadstream.h @@ -40,7 +40,7 @@ public: \param buffer user-supplied buffer. \param bufferSize size of buffer in bytes. Must >=4 bytes. */ - FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { RAPIDJSON_ASSERT(fp_ != 0); RAPIDJSON_ASSERT(bufferSize >= 4); Read(); @@ -79,7 +79,7 @@ private: } } - FILE* fp_; + std::FILE* fp_; Ch *buffer_; size_t bufferSize_; Ch *bufferLast_; diff --git a/include/rapidjson/filestream.h b/include/rapidjson/filestream.h index a4f559c..a2e7172 100644 --- a/include/rapidjson/filestream.h +++ b/include/rapidjson/filestream.h @@ -36,7 +36,7 @@ class FileStream { public: typedef char Ch; //!< Character type. Only support char. - FileStream(FILE* fp) : fp_(fp), current_('\0'), count_(0) { Read(); } + FileStream(std::FILE* fp) : fp_(fp), current_('\0'), count_(0) { Read(); } char Peek() const { return current_; } char Take() { char c = current_; Read(); return c; } size_t Tell() const { return count_; } @@ -63,7 +63,7 @@ private: current_ = '\0'; } - FILE* fp_; + std::FILE* fp_; char current_; size_t count_; }; diff --git a/include/rapidjson/filewritestream.h b/include/rapidjson/filewritestream.h index cecd700..2f4977d 100644 --- a/include/rapidjson/filewritestream.h +++ b/include/rapidjson/filewritestream.h @@ -34,7 +34,7 @@ class FileWriteStream { public: typedef char Ch; //!< Character type. Only support char. - FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { RAPIDJSON_ASSERT(fp_ != 0); } @@ -80,7 +80,7 @@ private: FileWriteStream(const FileWriteStream&); FileWriteStream& operator=(const FileWriteStream&); - FILE* fp_; + std::FILE* fp_; char *buffer_; char *bufferEnd_; char *current_; From 2aab79207e5165190c360a0bc30eecae9e08306e Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Wed, 26 Nov 2014 23:11:00 +0100 Subject: [PATCH 3/3] GenericValue: improve copying performance The GenericValue "copy" constructor (with Allocator) uses a temporary GenericDocument object to perform the deep copying with the provided allocator. This leads to the temporary allocation of the `Stack` memory, even in case of shallow values (numbers, etc.). This patch improves the performance of this operation by only resorting the the SAX Handler implementation in case of Array or Object values. --- include/rapidjson/document.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 047bc66..56e2f2e 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -1896,9 +1896,26 @@ template inline GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) { - GenericDocument d(&allocator); - rhs.Accept(d); - RawAssign(*d.stack_.template Pop(1)); + 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)); + } + break; + case kStringType: + if (rhs.flags_ == kConstStringFlag) { + flags_ = rhs.flags_; + data_ = *reinterpret_cast(&rhs.data_); + } else { + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + } + break; + default: // kNumberType, kTrueType, kFalseType, kNullType + flags_ = rhs.flags_; + data_ = *reinterpret_cast(&rhs.data_); + } } RAPIDJSON_NAMESPACE_END