Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give Json::Value move members and fix swap #339

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/ripple/json/api/json_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
49 changes: 49 additions & 0 deletions src/ripple/json/impl/Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//==============================================================================

#include "../../../beast/beast/unit_test/suite.h"
#include "../../../beast/beast/utility/type_name.h"

namespace ripple {

Expand All @@ -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 ();
}
};

Expand Down
35 changes: 34 additions & 1 deletion src/ripple/json/impl/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now you have made this change, it seems clear to me that Value::swap isn't correct, because it doesn't swap the values of itemIsUsed_ and memberNameIsStatic_ in the case that JSON_VALUE_USE_INTERNAL_MAP is defined.

Is my reasoning correct? If so, could I convince you to make this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Apr 30, 2014, at 3:02 PM, Tom Swirly notifications@github.com wrote:

In src/ripple/json/impl/json_value.cpp:

@@ -554,6 +554,26 @@ 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

Now you have made this change, it seems clear to me that Value::swap isn't correct, because it doesn't swap the values of itemIsUsed_ and memberNameIsStatic_ in the case that JSON_VALUE_USE_INTERNAL_MAP is defined.

Is my reasoning correct? If so, could I convince you to make this change?

Done (I think):

https://github.com/ripple/rippled/pull/339/commits

Howard

, 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
Expand Down