move ctors

* 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
This commit is contained in:
Motti 2015-04-20 17:44:47 +03:00 committed by Christopher Dunn
parent a4ce2829dc
commit 2b00891a86
4 changed files with 82 additions and 13 deletions

View File

@ -56,30 +56,59 @@
// Storages, and 64 bits integer support is disabled. // Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1 // #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 // Microsoft Visual Studio 6 only support conversion from __int64 to double
// (no conversion from unsigned __int64). // (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' // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
// characters in the debug information) // characters in the debug information)
// All projects I've ever seen with VS6 were using this globally (not bothering // All projects I've ever seen with VS6 were using this globally (not bothering
// with pragma push/pop). // with pragma push/pop).
# pragma warning(disable : 4786) # 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. /// Indicates that the following function is deprecated.
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#elif defined(__clang__) && defined(__has_feature) # endif
#if __has_feature(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) #endif // defined(_MSC_VER)
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) #ifndef JSON_HAS_RVALUE_REFERENCES
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) #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 #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) #if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message) #define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED) #endif // if !defined(JSONCPP_DEPRECATED)

View File

@ -212,6 +212,9 @@ private:
CZString(ArrayIndex index); CZString(ArrayIndex index);
CZString(char const* str, unsigned length, DuplicationPolicy allocate); CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other); CZString(CZString const& other);
#if JSON_HAS_RVALUE_REFERENCES
CZString(CZString&& other);
#endif
~CZString(); ~CZString();
CZString& operator=(CZString other); CZString& operator=(CZString other);
bool operator<(CZString const& other) const; bool operator<(CZString const& other) const;
@ -294,6 +297,10 @@ Json::Value obj_value(Json::objectValue); // {}
Value(bool value); Value(bool value);
/// Deep copy. /// Deep copy.
Value(const Value& other); Value(const Value& other);
#if JSON_HAS_RVALUE_REFERENCES
/// Move constructor
Value(Value&& other);
#endif
~Value(); ~Value();
/// Deep copy, then swap(other). /// Deep copy, then swap(other).

View File

@ -237,6 +237,15 @@ Value::CZString::CZString(const CZString& other)
storage_.length_ = other.storage_.length_; 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() { Value::CZString::~CZString() {
if (cstr_ && storage_.policy_ == duplicate) if (cstr_ && storage_.policy_ == duplicate)
releaseStringValue(const_cast<char*>(cstr_)); releaseStringValue(const_cast<char*>(cstr_));
@ -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() { Value::~Value() {
switch (type_) { switch (type_) {
case nullValue: case nullValue:

View File

@ -2497,6 +2497,19 @@ JSONTEST_FIXTURE(IteratorTest, const) {
JSONTEST_ASSERT_STRING_EQUAL(expected, out.str()); 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[]) { int main(int argc, const char* argv[]) {
JsonTest::Runner runner; JsonTest::Runner runner;
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
@ -2570,5 +2583,7 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes); JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, const); JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, const);
JSONTEST_REGISTER_FIXTURE(runner, RValueTest, moveConstruction);
return runner.runCommandLine(argc, argv); return runner.runCommandLine(argc, argv);
} }