From 8996c377aad3a333a9bada1cfe7d5924e71a3269 Mon Sep 17 00:00:00 2001 From: Dhruv Paranjape Date: Sat, 8 Jul 2017 17:27:07 +0530 Subject: [PATCH 1/3] add move assignment operator for Json::Value class. --- include/json/value.h | 17 +++++++++++++---- src/lib_json/json_value.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index c39f423..4aefb10 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -23,7 +23,7 @@ #endif //Conditional NORETURN attribute on the throw functions would: -// a) suppress false positives from static code analysis +// a) suppress false positives from static code analysis // b) possibly improve optimization opportunities. #if !defined(JSONCPP_NORETURN) # if defined(_MSC_VER) @@ -64,7 +64,7 @@ protected: /** Exceptions which the user cannot easily avoid. * * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input - * + * * \remark derived from Json::Exception */ class JSON_API RuntimeError : public Exception { @@ -75,7 +75,7 @@ public: /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. * * These are precondition-violations (user bugs) and internal errors (our bugs). - * + * * \remark derived from Json::Exception */ class JSON_API LogicError : public Exception { @@ -322,12 +322,21 @@ Json::Value obj_value(Json::objectValue); // {} /// Deep copy, then swap(other). /// \note Over-write existing comments. To preserve comments, use #swapPayload(). - Value& operator=(Value other); + Value& operator=(const Value& other); +#if JSON_HAS_RVALUE_REFERENCES + Value& operator=(Value&& other); +#endif + /// Swap everything. void swap(Value& other); /// Swap values but leave comments and source offsets in place. void swapPayload(Value& other); + /// copy everything. + void copy(const Value& other); + /// copy values but leave comments and source offsets in place. + void copyPayload(const Value& other); + ValueType type() const; /// Compare payload only, not comments etc. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index dc12964..49b88f9 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -398,7 +398,7 @@ Value::Value(double value) { Value::Value(const char* value) { initBasic(stringValue, true); - JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor"); + JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor"); value_.string_ = duplicateAndPrefixStringValue(value, static_cast(strlen(value))); } @@ -508,10 +508,18 @@ Value::~Value() { value_.uint_ = 0; } -Value& Value::operator=(Value other) { +Value& Value::operator=(const Value& other) { + swap(const_cast(other)); + return *this; +} + +#if JSON_HAS_RVALUE_REFERENCES +Value& Value::operator=(Value&& other) { + initBasic(nullValue); swap(other); return *this; } +#endif void Value::swapPayload(Value& other) { ValueType temp = type_; @@ -523,6 +531,12 @@ void Value::swapPayload(Value& other) { other.allocated_ = temp2 & 0x1; } +void Value::copyPayload(const Value& other) { + type_ = other.type_; + value_ = other.value_; + allocated_ = other.allocated_; +} + void Value::swap(Value& other) { swapPayload(other); std::swap(comments_, other.comments_); @@ -530,6 +544,13 @@ void Value::swap(Value& other) { std::swap(limit_, other.limit_); } +void Value::copy(const Value& other) { + copyPayload(other); + comments_ = other.comments_; + start_ = other.start_; + limit_ = other.limit_; +} + ValueType Value::type() const { return type_; } int Value::compare(const Value& other) const { From 23c44d9f9eed8a7ff95daca9bd44526067c144c0 Mon Sep 17 00:00:00 2001 From: Dhruv Paranjape Date: Sat, 8 Jul 2017 17:30:47 +0530 Subject: [PATCH 2/3] overload append function for R value references. --- include/json/value.h | 4 ++++ src/lib_json/json_value.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index 4aefb10..6b40831 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -447,6 +447,10 @@ Json::Value obj_value(Json::objectValue); // {} /// Equivalent to jsonvalue[jsonvalue.size()] = value; Value& append(const Value& value); +#ifdef JSON_HAS_RVALUE_REFERENCES + Value& append(Value&& value); +#endif + /// Access an object value by name, create a null member if it does not exist. /// \note Because of our implementation, keys are limited to 2^30 -1 chars. /// Exceeding that will cause an exception. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 49b88f9..adae5a1 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1145,6 +1145,10 @@ Value const& Value::operator[](CppTL::ConstString const& key) const Value& Value::append(const Value& value) { return (*this)[size()] = value; } +#ifdef JSON_HAS_RVALUE_REFERENCES + Value& Value::append(Value&& value) { return (*this)[size()] = value; } +#endif + Value Value::get(char const* key, char const* cend, Value const& defaultValue) const { Value const* found = find(key, cend); From 0ba8bd73f505ab6a3e9a5abf66307d5c21c6e4a0 Mon Sep 17 00:00:00 2001 From: Dhruv Paranjape Date: Sat, 8 Jul 2017 17:47:13 +0530 Subject: [PATCH 3/3] add move assignment operator for CZString and change copy assignment to const reference. --- include/json/value.h | 9 +++++++-- src/lib_json/json_value.cpp | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 6b40831..ba7365c 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -233,7 +233,12 @@ private: CZString(CZString&& other); #endif ~CZString(); - CZString& operator=(CZString other); + CZString& operator=(const CZString& other); + +#if JSON_HAS_RVALUE_REFERENCES + CZString& operator=(CZString&& other); +#endif + bool operator<(CZString const& other) const; bool operator==(CZString const& other) const; ArrayIndex index() const; @@ -447,7 +452,7 @@ Json::Value obj_value(Json::objectValue); // {} /// Equivalent to jsonvalue[jsonvalue.size()] = value; Value& append(const Value& value); -#ifdef JSON_HAS_RVALUE_REFERENCES +#if JSON_HAS_RVALUE_REFERENCES Value& append(Value&& value); #endif diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index adae5a1..5f5cf8b 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -292,11 +292,21 @@ void Value::CZString::swap(CZString& other) { std::swap(index_, other.index_); } -Value::CZString& Value::CZString::operator=(CZString other) { - swap(other); +Value::CZString& Value::CZString::operator=(const CZString& other) { + cstr_ = other.cstr_; + index_ = other.index_; return *this; } +#if JSON_HAS_RVALUE_REFERENCES +Value::CZString& Value::CZString::operator=(CZString&& other) { + cstr_ = other.cstr_; + index_ = other.index_; + other.cstr_ = nullptr; + return *this; +} +#endif + bool Value::CZString::operator<(const CZString& other) const { if (!cstr_) return index_ < other.index_; //return strcmp(cstr_, other.cstr_) < 0; @@ -1145,7 +1155,7 @@ Value const& Value::operator[](CppTL::ConstString const& key) const Value& Value::append(const Value& value) { return (*this)[size()] = value; } -#ifdef JSON_HAS_RVALUE_REFERENCES +#if JSON_HAS_RVALUE_REFERENCES Value& Value::append(Value&& value) { return (*this)[size()] = value; } #endif