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 {