diff --git a/src/ripple/json/api/json_value.h b/src/ripple/json/api/json_value.h index 3a92e8d6852..cb35bf228ec 100644 --- a/src/ripple/json/api/json_value.h +++ b/src/ripple/json/api/json_value.h @@ -215,6 +215,10 @@ class JSON_API Value ~Value (); Value& operator= ( const Value& other ); + + Value ( Value&& other ); + Value& operator= ( Value&& other ); + /// Swap values. /// \note Currently, comments are intentionally not swapped, for /// both logic and efficiency. diff --git a/src/ripple/json/impl/Tests.cpp b/src/ripple/json/impl/Tests.cpp index db64abe59f6..23e2043b7e3 100644 --- a/src/ripple/json/impl/Tests.cpp +++ b/src/ripple/json/impl/Tests.cpp @@ -18,6 +18,7 @@ //============================================================================== #include "../../../beast/beast/unit_test/suite.h" +#include "../../../beast/beast/utility/type_name.h" namespace ripple { @@ -37,9 +38,57 @@ class JsonCpp_test : public beast::unit_test::suite pass (); } + void + test_copy () + { + Json::Value v1{2.5}; + expect (v1.isDouble ()); + expect (v1.asDouble () == 2.5); + + Json::Value v2 = v1; + expect (v1.isDouble ()); + expect (v1.asDouble () == 2.5); + expect (v2.isDouble ()); + expect (v2.asDouble () == 2.5); + expect (v1 == v2); + + v1 = v2; + expect (v1.isDouble ()); + expect (v1.asDouble () == 2.5); + expect (v2.isDouble ()); + expect (v2.asDouble () == 2.5); + expect (v1 == v2); + + pass (); + } + + void + test_move () + { + Json::Value v1{2.5}; + expect (v1.isDouble ()); + expect (v1.asDouble () == 2.5); + + Json::Value v2 = std::move(v1); + expect (v1.isNull ()); + expect (v2.isDouble ()); + expect (v2.asDouble () == 2.5); + expect (v1 != v2); + + v1 = std::move(v2); + expect (v1.isDouble ()); + expect (v1.asDouble () == 2.5); + expect (v2.isNull ()); + expect (v1 != v2); + + pass (); + } + void run () { testBadJson (); + test_copy (); + test_move (); } }; diff --git a/src/ripple/json/impl/json_value.cpp b/src/ripple/json/impl/json_value.cpp index 4d6a1cf46e7..32b3997aa17 100644 --- a/src/ripple/json/impl/json_value.cpp +++ b/src/ripple/json/impl/json_value.cpp @@ -554,16 +554,49 @@ Value::operator= ( const Value& other ) return *this; } +Value::Value ( Value&& other ) + : value_ ( other.value_ ) + , type_ ( other.type_ ) + , allocated_ ( other.allocated_ ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_ ( other.itemIsUsed_ ) + , memberNameIsStatic_ ( other.memberNameIsStatic_ ) +#endif // JSON_VALUE_USE_INTERNAL_MAP + , comments_ ( other.comments_ ) +{ + std::memset( &other, 0, sizeof(Value) ); +} + +Value& +Value::operator= ( Value&& other ) +{ + swap ( other ); + return *this; +} + void Value::swap ( Value& other ) { + std::swap ( value_, other.value_ ); + ValueType temp = type_; type_ = other.type_; other.type_ = temp; - std::swap ( value_, other.value_ ); + int temp2 = allocated_; allocated_ = other.allocated_; other.allocated_ = temp2; + +# ifdef JSON_VALUE_USE_INTERNAL_MAP + unsigned temp3 = itemIsUsed_; + itemIsUsed_ = other.itemIsUsed_; + other.itemIsUsed_ = itemIsUsed_; + + temp2 = memberNameIsStatic_; + memberNameIsStatic_ = other.memberNameIsStatic_; + other.memberNameIsStatic_ = temp2 +# endif + std::swap(comments_, other.comments_); } ValueType