Merge pull request #490 from open-source-parsers/null-singleton

Use a Myers Singleton for null
This commit is contained in:
Christopher Dunn 2016-06-27 00:12:23 -05:00 committed by GitHub
commit 7e4df50d17
5 changed files with 34 additions and 20 deletions

View File

@ -64,7 +64,7 @@ ENDMACRO()
#SET( JSONCPP_VERSION_MAJOR X ) #SET( JSONCPP_VERSION_MAJOR X )
#SET( JSONCPP_VERSION_MINOR Y ) #SET( JSONCPP_VERSION_MINOR Y )
#SET( JSONCPP_VERSION_PATCH Z ) #SET( JSONCPP_VERSION_PATCH Z )
SET( JSONCPP_VERSION 1.7.2 ) SET( JSONCPP_VERSION 1.7.3 )
jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION ) jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION )
#IF(NOT JSONCPP_VERSION_FOUND) #IF(NOT JSONCPP_VERSION_FOUND)
# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z") # MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z")

View File

@ -190,6 +190,8 @@ public:
static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
/// Minimum signed integer value that can be stored in a Json::Value. /// Minimum signed integer value that can be stored in a Json::Value.
static const LargestInt minLargestInt; static const LargestInt minLargestInt;
/// Maximum signed integer value that can be stored in a Json::Value. /// Maximum signed integer value that can be stored in a Json::Value.

View File

@ -3,10 +3,10 @@
#ifndef JSON_VERSION_H_INCLUDED #ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED # define JSON_VERSION_H_INCLUDED
# define JSONCPP_VERSION_STRING "1.7.2" # define JSONCPP_VERSION_STRING "1.7.3"
# define JSONCPP_VERSION_MAJOR 1 # define JSONCPP_VERSION_MAJOR 1
# define JSONCPP_VERSION_MINOR 7 # define JSONCPP_VERSION_MINOR 7
# define JSONCPP_VERSION_PATCH 2 # define JSONCPP_VERSION_PATCH 3
# define JSONCPP_VERSION_QUALIFIER # define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))

View File

@ -31,10 +31,22 @@ namespace Json {
#else #else
#define ALIGNAS(byte_alignment) #define ALIGNAS(byte_alignment)
#endif #endif
static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; //static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
const unsigned char& kNullRef = kNull[0]; //const unsigned char& kNullRef = kNull[0];
const Value& Value::null = reinterpret_cast<const Value&>(kNullRef); //const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
const Value& Value::nullRef = null; //const Value& Value::nullRef = null;
// static
Value const& Value::nullSingleton()
{
static Value const* nullStatic = new Value;
return *nullStatic;
}
// for backwards compatibility, we'll leave these global references around, but DO NOT
// use them in JSONCPP library code any more!
Value const& Value::null = Value::nullSingleton();
Value const& Value::nullRef = Value::nullSingleton();
const Int Value::minInt = Int(~(UInt(-1) / 2)); const Int Value::minInt = Int(~(UInt(-1) / 2));
const Int Value::maxInt = Int(UInt(-1) / 2); const Int Value::maxInt = Int(UInt(-1) / 2);
@ -972,7 +984,7 @@ Value& Value::operator[](ArrayIndex index) {
if (it != value_.map_->end() && (*it).first == key) if (it != value_.map_->end() && (*it).first == key)
return (*it).second; return (*it).second;
ObjectValues::value_type defaultValue(key, nullRef); ObjectValues::value_type defaultValue(key, nullSingleton());
it = value_.map_->insert(it, defaultValue); it = value_.map_->insert(it, defaultValue);
return (*it).second; return (*it).second;
} }
@ -989,11 +1001,11 @@ const Value& Value::operator[](ArrayIndex index) const {
type_ == nullValue || type_ == arrayValue, type_ == nullValue || type_ == arrayValue,
"in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
if (type_ == nullValue) if (type_ == nullValue)
return nullRef; return nullSingleton();
CZString key(index); CZString key(index);
ObjectValues::const_iterator it = value_.map_->find(key); ObjectValues::const_iterator it = value_.map_->find(key);
if (it == value_.map_->end()) if (it == value_.map_->end())
return nullRef; return nullSingleton();
return (*it).second; return (*it).second;
} }
@ -1027,7 +1039,7 @@ Value& Value::resolveReference(const char* key) {
if (it != value_.map_->end() && (*it).first == actualKey) if (it != value_.map_->end() && (*it).first == actualKey)
return (*it).second; return (*it).second;
ObjectValues::value_type defaultValue(actualKey, nullRef); ObjectValues::value_type defaultValue(actualKey, nullSingleton());
it = value_.map_->insert(it, defaultValue); it = value_.map_->insert(it, defaultValue);
Value& value = (*it).second; Value& value = (*it).second;
return value; return value;
@ -1047,7 +1059,7 @@ Value& Value::resolveReference(char const* key, char const* cend)
if (it != value_.map_->end() && (*it).first == actualKey) if (it != value_.map_->end() && (*it).first == actualKey)
return (*it).second; return (*it).second;
ObjectValues::value_type defaultValue(actualKey, nullRef); ObjectValues::value_type defaultValue(actualKey, nullSingleton());
it = value_.map_->insert(it, defaultValue); it = value_.map_->insert(it, defaultValue);
Value& value = (*it).second; Value& value = (*it).second;
return value; return value;
@ -1055,7 +1067,7 @@ Value& Value::resolveReference(char const* key, char const* cend)
Value Value::get(ArrayIndex index, const Value& defaultValue) const { Value Value::get(ArrayIndex index, const Value& defaultValue) const {
const Value* value = &((*this)[index]); const Value* value = &((*this)[index]);
return value == &nullRef ? defaultValue : *value; return value == &nullSingleton() ? defaultValue : *value;
} }
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
@ -1074,13 +1086,13 @@ Value const* Value::find(char const* key, char const* cend) const
const Value& Value::operator[](const char* key) const const Value& Value::operator[](const char* key) const
{ {
Value const* found = find(key, key + strlen(key)); Value const* found = find(key, key + strlen(key));
if (!found) return nullRef; if (!found) return nullSingleton();
return *found; return *found;
} }
Value const& Value::operator[](JSONCPP_STRING const& key) const Value const& Value::operator[](JSONCPP_STRING const& key) const
{ {
Value const* found = find(key.data(), key.data() + key.length()); Value const* found = find(key.data(), key.data() + key.length());
if (!found) return nullRef; if (!found) return nullSingleton();
return *found; return *found;
} }
@ -1103,7 +1115,7 @@ Value& Value::operator[](const CppTL::ConstString& key) {
Value const& Value::operator[](CppTL::ConstString const& key) const Value const& Value::operator[](CppTL::ConstString const& key) const
{ {
Value const* found = find(key.c_str(), key.end_c_str()); Value const* found = find(key.c_str(), key.end_c_str());
if (!found) return nullRef; if (!found) return nullSingleton();
return *found; return *found;
} }
#endif #endif
@ -1151,7 +1163,7 @@ Value Value::removeMember(const char* key)
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
"in Json::Value::removeMember(): requires objectValue"); "in Json::Value::removeMember(): requires objectValue");
if (type_ == nullValue) if (type_ == nullValue)
return nullRef; return nullSingleton();
Value removed; // null Value removed; // null
removeMember(key, key + strlen(key), &removed); removeMember(key, key + strlen(key), &removed);
@ -1538,7 +1550,7 @@ const Value& Path::resolve(const Value& root) const {
// Error: unable to resolve path (object value expected at position...) // Error: unable to resolve path (object value expected at position...)
} }
node = &((*node)[arg.key_]); node = &((*node)[arg.key_]);
if (node == &Value::nullRef) { if (node == &Value::nullSingleton()) {
// Error: unable to resolve path (object has no member named '' at // Error: unable to resolve path (object has no member named '' at
// position...) // position...)
} }
@ -1559,7 +1571,7 @@ Value Path::resolve(const Value& root, const Value& defaultValue) const {
if (!node->isObject()) if (!node->isObject())
return defaultValue; return defaultValue;
node = &((*node)[arg.key_]); node = &((*node)[arg.key_]);
if (node == &Value::nullRef) if (node == &Value::nullSingleton())
return defaultValue; return defaultValue;
} }
} }

View File

@ -1 +1 @@
1.7.2 1.7.3