Skip to content

Commit 7e4df50

Browse files
authored
Merge pull request #490 from open-source-parsers/null-singleton
Use a Myers Singleton for null
2 parents e0f9aab + 318f303 commit 7e4df50

File tree

5 files changed

+34
-20
lines changed

5 files changed

+34
-20
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ ENDMACRO()
6464
#SET( JSONCPP_VERSION_MAJOR X )
6565
#SET( JSONCPP_VERSION_MINOR Y )
6666
#SET( JSONCPP_VERSION_PATCH Z )
67-
SET( JSONCPP_VERSION 1.7.2 )
67+
SET( JSONCPP_VERSION 1.7.3 )
6868
jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION )
6969
#IF(NOT JSONCPP_VERSION_FOUND)
7070
# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z")

include/json/value.h

+2
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ class JSON_API Value {
190190

191191
static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
192192
static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
193+
static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
194+
193195
/// Minimum signed integer value that can be stored in a Json::Value.
194196
static const LargestInt minLargestInt;
195197
/// Maximum signed integer value that can be stored in a Json::Value.

include/json/version.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
#ifndef JSON_VERSION_H_INCLUDED
44
# define JSON_VERSION_H_INCLUDED
55

6-
# define JSONCPP_VERSION_STRING "1.7.2"
6+
# define JSONCPP_VERSION_STRING "1.7.3"
77
# define JSONCPP_VERSION_MAJOR 1
88
# define JSONCPP_VERSION_MINOR 7
9-
# define JSONCPP_VERSION_PATCH 2
9+
# define JSONCPP_VERSION_PATCH 3
1010
# define JSONCPP_VERSION_QUALIFIER
1111
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
1212

src/lib_json/json_value.cpp

+28-16
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,22 @@ namespace Json {
3131
#else
3232
#define ALIGNAS(byte_alignment)
3333
#endif
34-
static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
35-
const unsigned char& kNullRef = kNull[0];
36-
const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
37-
const Value& Value::nullRef = null;
34+
//static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
35+
//const unsigned char& kNullRef = kNull[0];
36+
//const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
37+
//const Value& Value::nullRef = null;
38+
39+
// static
40+
Value const& Value::nullSingleton()
41+
{
42+
static Value const* nullStatic = new Value;
43+
return *nullStatic;
44+
}
45+
46+
// for backwards compatibility, we'll leave these global references around, but DO NOT
47+
// use them in JSONCPP library code any more!
48+
Value const& Value::null = Value::nullSingleton();
49+
Value const& Value::nullRef = Value::nullSingleton();
3850

3951
const Int Value::minInt = Int(~(UInt(-1) / 2));
4052
const Int Value::maxInt = Int(UInt(-1) / 2);
@@ -972,7 +984,7 @@ Value& Value::operator[](ArrayIndex index) {
972984
if (it != value_.map_->end() && (*it).first == key)
973985
return (*it).second;
974986

975-
ObjectValues::value_type defaultValue(key, nullRef);
987+
ObjectValues::value_type defaultValue(key, nullSingleton());
976988
it = value_.map_->insert(it, defaultValue);
977989
return (*it).second;
978990
}
@@ -989,11 +1001,11 @@ const Value& Value::operator[](ArrayIndex index) const {
9891001
type_ == nullValue || type_ == arrayValue,
9901002
"in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
9911003
if (type_ == nullValue)
992-
return nullRef;
1004+
return nullSingleton();
9931005
CZString key(index);
9941006
ObjectValues::const_iterator it = value_.map_->find(key);
9951007
if (it == value_.map_->end())
996-
return nullRef;
1008+
return nullSingleton();
9971009
return (*it).second;
9981010
}
9991011

@@ -1027,7 +1039,7 @@ Value& Value::resolveReference(const char* key) {
10271039
if (it != value_.map_->end() && (*it).first == actualKey)
10281040
return (*it).second;
10291041

1030-
ObjectValues::value_type defaultValue(actualKey, nullRef);
1042+
ObjectValues::value_type defaultValue(actualKey, nullSingleton());
10311043
it = value_.map_->insert(it, defaultValue);
10321044
Value& value = (*it).second;
10331045
return value;
@@ -1047,15 +1059,15 @@ Value& Value::resolveReference(char const* key, char const* cend)
10471059
if (it != value_.map_->end() && (*it).first == actualKey)
10481060
return (*it).second;
10491061

1050-
ObjectValues::value_type defaultValue(actualKey, nullRef);
1062+
ObjectValues::value_type defaultValue(actualKey, nullSingleton());
10511063
it = value_.map_->insert(it, defaultValue);
10521064
Value& value = (*it).second;
10531065
return value;
10541066
}
10551067

10561068
Value Value::get(ArrayIndex index, const Value& defaultValue) const {
10571069
const Value* value = &((*this)[index]);
1058-
return value == &nullRef ? defaultValue : *value;
1070+
return value == &nullSingleton() ? defaultValue : *value;
10591071
}
10601072

10611073
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
@@ -1074,13 +1086,13 @@ Value const* Value::find(char const* key, char const* cend) const
10741086
const Value& Value::operator[](const char* key) const
10751087
{
10761088
Value const* found = find(key, key + strlen(key));
1077-
if (!found) return nullRef;
1089+
if (!found) return nullSingleton();
10781090
return *found;
10791091
}
10801092
Value const& Value::operator[](JSONCPP_STRING const& key) const
10811093
{
10821094
Value const* found = find(key.data(), key.data() + key.length());
1083-
if (!found) return nullRef;
1095+
if (!found) return nullSingleton();
10841096
return *found;
10851097
}
10861098

@@ -1103,7 +1115,7 @@ Value& Value::operator[](const CppTL::ConstString& key) {
11031115
Value const& Value::operator[](CppTL::ConstString const& key) const
11041116
{
11051117
Value const* found = find(key.c_str(), key.end_c_str());
1106-
if (!found) return nullRef;
1118+
if (!found) return nullSingleton();
11071119
return *found;
11081120
}
11091121
#endif
@@ -1151,7 +1163,7 @@ Value Value::removeMember(const char* key)
11511163
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
11521164
"in Json::Value::removeMember(): requires objectValue");
11531165
if (type_ == nullValue)
1154-
return nullRef;
1166+
return nullSingleton();
11551167

11561168
Value removed; // null
11571169
removeMember(key, key + strlen(key), &removed);
@@ -1538,7 +1550,7 @@ const Value& Path::resolve(const Value& root) const {
15381550
// Error: unable to resolve path (object value expected at position...)
15391551
}
15401552
node = &((*node)[arg.key_]);
1541-
if (node == &Value::nullRef) {
1553+
if (node == &Value::nullSingleton()) {
15421554
// Error: unable to resolve path (object has no member named '' at
15431555
// position...)
15441556
}
@@ -1559,7 +1571,7 @@ Value Path::resolve(const Value& root, const Value& defaultValue) const {
15591571
if (!node->isObject())
15601572
return defaultValue;
15611573
node = &((*node)[arg.key_]);
1562-
if (node == &Value::nullRef)
1574+
if (node == &Value::nullSingleton())
15631575
return defaultValue;
15641576
}
15651577
}

version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.7.2
1+
1.7.3

0 commit comments

Comments
 (0)