Skip to content

Commit 2b00891

Browse files
lanzkroncdunn2001
authored andcommitted
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
1 parent a4ce282 commit 2b00891

File tree

4 files changed

+82
-13
lines changed

4 files changed

+82
-13
lines changed

include/json/config.h

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,30 +56,59 @@
5656
// Storages, and 64 bits integer support is disabled.
5757
// #define JSON_NO_INT64 1
5858

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

70-
#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
71+
# if _MSC_VER >= 1500 // MSVC 2008
7172
/// Indicates that the following function is deprecated.
72-
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
73-
#elif defined(__clang__) && defined(__has_feature)
74-
#if __has_feature(attribute_deprecated_with_message)
75-
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
76-
#endif
77-
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
78-
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
79-
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
80-
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
73+
# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
74+
# endif
75+
76+
#endif // defined(_MSC_VER)
77+
78+
79+
#ifndef JSON_HAS_RVALUE_REFERENCES
80+
81+
#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
82+
#define JSON_HAS_RVALUE_REFERENCES 1
83+
#endif // MSVC >= 2010
84+
85+
#ifdef __clang__
86+
#if __has_feature(cxx_rvalue_references)
87+
#define JSON_HAS_RVALUE_REFERENCES 1
88+
#endif // has_feature
89+
90+
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
91+
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
92+
#define JSON_HAS_RVALUE_REFERENCES 1
93+
#endif // GXX_EXPERIMENTAL
94+
95+
#endif // __clang__ || __GNUC__
96+
97+
#endif // not defined JSON_HAS_RVALUE_REFERENCES
98+
99+
#ifndef JSON_HAS_RVALUE_REFERENCES
100+
#define JSON_HAS_RVALUE_REFERENCES 0
81101
#endif
82102

103+
#ifdef __clang__
104+
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
105+
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
106+
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
107+
# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
108+
# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
109+
# endif // GNUC version
110+
#endif // __clang__ || __GNUC__
111+
83112
#if !defined(JSONCPP_DEPRECATED)
84113
#define JSONCPP_DEPRECATED(message)
85114
#endif // if !defined(JSONCPP_DEPRECATED)

include/json/value.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ class JSON_API Value {
212212
CZString(ArrayIndex index);
213213
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
214214
CZString(CZString const& other);
215+
#if JSON_HAS_RVALUE_REFERENCES
216+
CZString(CZString&& other);
217+
#endif
215218
~CZString();
216219
CZString& operator=(CZString other);
217220
bool operator<(CZString const& other) const;
@@ -294,6 +297,10 @@ Json::Value obj_value(Json::objectValue); // {}
294297
Value(bool value);
295298
/// Deep copy.
296299
Value(const Value& other);
300+
#if JSON_HAS_RVALUE_REFERENCES
301+
/// Move constructor
302+
Value(Value&& other);
303+
#endif
297304
~Value();
298305

299306
/// Deep copy, then swap(other).

src/lib_json/json_value.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,15 @@ Value::CZString::CZString(const CZString& other)
237237
storage_.length_ = other.storage_.length_;
238238
}
239239

240+
#if JSON_HAS_RVALUE_REFERENCES
241+
Value::CZString::CZString(CZString&& other)
242+
: cstr_(other.cstr_),
243+
index_(other.index_)
244+
{
245+
other.cstr_ = 0;
246+
}
247+
#endif
248+
240249
Value::CZString::~CZString() {
241250
if (cstr_ && storage_.policy_ == duplicate)
242251
releaseStringValue(const_cast<char*>(cstr_));
@@ -425,6 +434,15 @@ Value::Value(Value const& other)
425434
}
426435
}
427436

437+
#if JSON_HAS_RVALUE_REFERENCES
438+
// Move constructor
439+
Value::Value(Value&& other)
440+
{
441+
initBasic(nullValue);
442+
swap(other);
443+
}
444+
#endif
445+
428446
Value::~Value() {
429447
switch (type_) {
430448
case nullValue:

src/test_lib_json/main.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,6 +2497,19 @@ JSONTEST_FIXTURE(IteratorTest, const) {
24972497
JSONTEST_ASSERT_STRING_EQUAL(expected, out.str());
24982498
}
24992499

2500+
struct RValueTest : JsonTest::TestCase {};
2501+
2502+
JSONTEST_FIXTURE(RValueTest, moveConstruction) {
2503+
#if JSON_HAS_RVALUE_REFERENCES
2504+
Json::Value json;
2505+
json["key"] = "value";
2506+
Json::Value moved = std::move(json);
2507+
JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not equal.
2508+
JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type());
2509+
JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type());
2510+
#endif
2511+
}
2512+
25002513
int main(int argc, const char* argv[]) {
25012514
JsonTest::Runner runner;
25022515
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
@@ -2570,5 +2583,7 @@ int main(int argc, const char* argv[]) {
25702583
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes);
25712584
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, const);
25722585

2586+
JSONTEST_REGISTER_FIXTURE(runner, RValueTest, moveConstruction);
2587+
25732588
return runner.runCommandLine(argc, argv);
25742589
}

0 commit comments

Comments
 (0)