Skip to content

Commit 414b179

Browse files
authored
Merge pull request #635 from Dark-Passenger/master
Add move assignment operator for Json::Value class and overload append member function for RValue references resolves #621
2 parents a679dde + 0ba8bd7 commit 414b179

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

include/json/value.h

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#endif
2424

2525
//Conditional NORETURN attribute on the throw functions would:
26-
// a) suppress false positives from static code analysis
26+
// a) suppress false positives from static code analysis
2727
// b) possibly improve optimization opportunities.
2828
#if !defined(JSONCPP_NORETURN)
2929
# if defined(_MSC_VER)
@@ -64,7 +64,7 @@ class JSON_API Exception : public std::exception {
6464
/** Exceptions which the user cannot easily avoid.
6565
*
6666
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
67-
*
67+
*
6868
* \remark derived from Json::Exception
6969
*/
7070
class JSON_API RuntimeError : public Exception {
@@ -75,7 +75,7 @@ class JSON_API RuntimeError : public Exception {
7575
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
7676
*
7777
* These are precondition-violations (user bugs) and internal errors (our bugs).
78-
*
78+
*
7979
* \remark derived from Json::Exception
8080
*/
8181
class JSON_API LogicError : public Exception {
@@ -233,7 +233,12 @@ class JSON_API Value {
233233
CZString(CZString&& other);
234234
#endif
235235
~CZString();
236-
CZString& operator=(CZString other);
236+
CZString& operator=(const CZString& other);
237+
238+
#if JSON_HAS_RVALUE_REFERENCES
239+
CZString& operator=(CZString&& other);
240+
#endif
241+
237242
bool operator<(CZString const& other) const;
238243
bool operator==(CZString const& other) const;
239244
ArrayIndex index() const;
@@ -322,12 +327,21 @@ Json::Value obj_value(Json::objectValue); // {}
322327

323328
/// Deep copy, then swap(other).
324329
/// \note Over-write existing comments. To preserve comments, use #swapPayload().
325-
Value& operator=(Value other);
330+
Value& operator=(const Value& other);
331+
#if JSON_HAS_RVALUE_REFERENCES
332+
Value& operator=(Value&& other);
333+
#endif
334+
326335
/// Swap everything.
327336
void swap(Value& other);
328337
/// Swap values but leave comments and source offsets in place.
329338
void swapPayload(Value& other);
330339

340+
/// copy everything.
341+
void copy(const Value& other);
342+
/// copy values but leave comments and source offsets in place.
343+
void copyPayload(const Value& other);
344+
331345
ValueType type() const;
332346

333347
/// Compare payload only, not comments etc.
@@ -438,6 +452,10 @@ Json::Value obj_value(Json::objectValue); // {}
438452
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
439453
Value& append(const Value& value);
440454

455+
#if JSON_HAS_RVALUE_REFERENCES
456+
Value& append(Value&& value);
457+
#endif
458+
441459
/// Access an object value by name, create a null member if it does not exist.
442460
/// \note Because of our implementation, keys are limited to 2^30 -1 chars.
443461
/// Exceeding that will cause an exception.

src/lib_json/json_value.cpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,21 @@ void Value::CZString::swap(CZString& other) {
292292
std::swap(index_, other.index_);
293293
}
294294

295-
Value::CZString& Value::CZString::operator=(CZString other) {
296-
swap(other);
295+
Value::CZString& Value::CZString::operator=(const CZString& other) {
296+
cstr_ = other.cstr_;
297+
index_ = other.index_;
297298
return *this;
298299
}
299300

301+
#if JSON_HAS_RVALUE_REFERENCES
302+
Value::CZString& Value::CZString::operator=(CZString&& other) {
303+
cstr_ = other.cstr_;
304+
index_ = other.index_;
305+
other.cstr_ = nullptr;
306+
return *this;
307+
}
308+
#endif
309+
300310
bool Value::CZString::operator<(const CZString& other) const {
301311
if (!cstr_) return index_ < other.index_;
302312
//return strcmp(cstr_, other.cstr_) < 0;
@@ -398,7 +408,7 @@ Value::Value(double value) {
398408

399409
Value::Value(const char* value) {
400410
initBasic(stringValue, true);
401-
JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
411+
JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
402412
value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
403413
}
404414

@@ -508,10 +518,18 @@ Value::~Value() {
508518
value_.uint_ = 0;
509519
}
510520

511-
Value& Value::operator=(Value other) {
521+
Value& Value::operator=(const Value& other) {
522+
swap(const_cast<Value&>(other));
523+
return *this;
524+
}
525+
526+
#if JSON_HAS_RVALUE_REFERENCES
527+
Value& Value::operator=(Value&& other) {
528+
initBasic(nullValue);
512529
swap(other);
513530
return *this;
514531
}
532+
#endif
515533

516534
void Value::swapPayload(Value& other) {
517535
ValueType temp = type_;
@@ -523,13 +541,26 @@ void Value::swapPayload(Value& other) {
523541
other.allocated_ = temp2 & 0x1;
524542
}
525543

544+
void Value::copyPayload(const Value& other) {
545+
type_ = other.type_;
546+
value_ = other.value_;
547+
allocated_ = other.allocated_;
548+
}
549+
526550
void Value::swap(Value& other) {
527551
swapPayload(other);
528552
std::swap(comments_, other.comments_);
529553
std::swap(start_, other.start_);
530554
std::swap(limit_, other.limit_);
531555
}
532556

557+
void Value::copy(const Value& other) {
558+
copyPayload(other);
559+
comments_ = other.comments_;
560+
start_ = other.start_;
561+
limit_ = other.limit_;
562+
}
563+
533564
ValueType Value::type() const { return type_; }
534565

535566
int Value::compare(const Value& other) const {
@@ -1124,6 +1155,10 @@ Value const& Value::operator[](CppTL::ConstString const& key) const
11241155

11251156
Value& Value::append(const Value& value) { return (*this)[size()] = value; }
11261157

1158+
#if JSON_HAS_RVALUE_REFERENCES
1159+
Value& Value::append(Value&& value) { return (*this)[size()] = value; }
1160+
#endif
1161+
11271162
Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
11281163
{
11291164
Value const* found = find(key, cend);

0 commit comments

Comments
 (0)