Skip to content

Commit 34bdbb5

Browse files
committed
Merge pull request open-source-parsers#267 from cdunn2001/moveSemantics
move ctors
2 parents a4ce282 + 527965c commit 34bdbb5

File tree

4 files changed

+81
-17
lines changed

4 files changed

+81
-17
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: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,7 @@ void Value::CommentInfo::setComment(const char* text, size_t len) {
218218
Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
219219

220220
Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
221-
: cstr_(str)
222-
{
221+
: cstr_(str) {
223222
// allocate != duplicate
224223
storage_.policy_ = allocate & 0x3;
225224
storage_.length_ = ulength & 0x3FFFFFFF;
@@ -228,15 +227,21 @@ Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy a
228227
Value::CZString::CZString(const CZString& other)
229228
: cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
230229
? duplicateStringValue(other.cstr_, other.storage_.length_)
231-
: other.cstr_)
232-
{
230+
: other.cstr_) {
233231
storage_.policy_ = (other.cstr_
234232
? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
235233
? noDuplication : duplicate)
236234
: static_cast<DuplicationPolicy>(other.storage_.policy_));
237235
storage_.length_ = other.storage_.length_;
238236
}
239237

238+
#if JSON_HAS_RVALUE_REFERENCES
239+
Value::CZString::CZString(CZString&& other)
240+
: cstr_(other.cstr_), index_(other.index_) {
241+
other.cstr_ = nullptr;
242+
}
243+
#endif
244+
240245
Value::CZString::~CZString() {
241246
if (cstr_ && storage_.policy_ == duplicate)
242247
releaseStringValue(const_cast<char*>(cstr_));
@@ -425,6 +430,14 @@ Value::Value(Value const& other)
425430
}
426431
}
427432

433+
#if JSON_HAS_RVALUE_REFERENCES
434+
// Move constructor
435+
Value::Value(Value&& other) {
436+
initBasic(nullValue);
437+
swap(other);
438+
}
439+
#endif
440+
428441
Value::~Value() {
429442
switch (type_) {
430443
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)