Skip to content

Commit

Permalink
move ctors
Browse files Browse the repository at this point in the history
* Add move constructor to Value::CZString
* Add unit test for Value move constructor
* Allow includer to specify in advance the value for
JSON_HAS_RVALUE_REFERENCES
  • Loading branch information
lanzkron authored and cdunn2001 committed Oct 20, 2015
1 parent a4ce282 commit 2b00891
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 13 deletions.
55 changes: 42 additions & 13 deletions include/json/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,59 @@
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1

#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6
#if defined(_MSC_VER) // MSVC
# if _MSC_VER <= 1200 // MSVC 6
// Microsoft Visual Studio 6 only support conversion from __int64 to double
// (no conversion from unsigned __int64).
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
// characters in the debug information)
// All projects I've ever seen with VS6 were using this globally (not bothering
// with pragma push/pop).
# pragma warning(disable : 4786)
#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6
# endif // MSVC 6

#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
# if _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated.
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#elif defined(__clang__) && defined(__has_feature)
#if __has_feature(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
# endif

#endif // defined(_MSC_VER)


#ifndef JSON_HAS_RVALUE_REFERENCES

#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // MSVC >= 2010

#ifdef __clang__
#if __has_feature(cxx_rvalue_references)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // has_feature

#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // GXX_EXPERIMENTAL

#endif // __clang__ || __GNUC__

#endif // not defined JSON_HAS_RVALUE_REFERENCES

#ifndef JSON_HAS_RVALUE_REFERENCES
#define JSON_HAS_RVALUE_REFERENCES 0
#endif

#ifdef __clang__
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
# endif // GNUC version
#endif // __clang__ || __GNUC__

#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)
Expand Down
7 changes: 7 additions & 0 deletions include/json/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ class JSON_API Value {
CZString(ArrayIndex index);
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other);
#if JSON_HAS_RVALUE_REFERENCES
CZString(CZString&& other);
#endif
~CZString();
CZString& operator=(CZString other);
bool operator<(CZString const& other) const;
Expand Down Expand Up @@ -294,6 +297,10 @@ Json::Value obj_value(Json::objectValue); // {}
Value(bool value);
/// Deep copy.
Value(const Value& other);
#if JSON_HAS_RVALUE_REFERENCES
/// Move constructor
Value(Value&& other);
#endif
~Value();

/// Deep copy, then swap(other).
Expand Down
18 changes: 18 additions & 0 deletions src/lib_json/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ Value::CZString::CZString(const CZString& other)
storage_.length_ = other.storage_.length_;
}

#if JSON_HAS_RVALUE_REFERENCES
Value::CZString::CZString(CZString&& other)
: cstr_(other.cstr_),
index_(other.index_)
{
other.cstr_ = 0;
}
#endif

Value::CZString::~CZString() {
if (cstr_ && storage_.policy_ == duplicate)
releaseStringValue(const_cast<char*>(cstr_));
Expand Down Expand Up @@ -425,6 +434,15 @@ Value::Value(Value const& other)
}
}

#if JSON_HAS_RVALUE_REFERENCES
// Move constructor
Value::Value(Value&& other)
{
initBasic(nullValue);
swap(other);
}
#endif

Value::~Value() {
switch (type_) {
case nullValue:
Expand Down
15 changes: 15 additions & 0 deletions src/test_lib_json/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2497,6 +2497,19 @@ JSONTEST_FIXTURE(IteratorTest, const) {
JSONTEST_ASSERT_STRING_EQUAL(expected, out.str());
}

struct RValueTest : JsonTest::TestCase {};

JSONTEST_FIXTURE(RValueTest, moveConstruction) {
#if JSON_HAS_RVALUE_REFERENCES
Json::Value json;
json["key"] = "value";
Json::Value moved = std::move(json);
JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not equal.
JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type());
JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type());
#endif
}

int main(int argc, const char* argv[]) {
JsonTest::Runner runner;
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
Expand Down Expand Up @@ -2570,5 +2583,7 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, const);

JSONTEST_REGISTER_FIXTURE(runner, RValueTest, moveConstruction);

return runner.runCommandLine(argc, argv);
}

0 comments on commit 2b00891

Please sign in to comment.