Add new JSON_USE_NULLREF flag

This patch adds a new flag, JSON_USE_NULLREF, which removes
the legacy singletons null, nullRef for consumers that require not
having static initialized globals, like Chromium.
This commit is contained in:
Jordan Bayles 2019-07-11 14:27:29 -07:00
parent 9ef812a097
commit 25c57812e2
3 changed files with 22 additions and 14 deletions

View File

@ -30,6 +30,11 @@
#define JSON_USE_EXCEPTION 1 #define JSON_USE_EXCEPTION 1
#endif #endif
// Temporary, tracked for removal with issue #982.
#ifndef JSON_USE_NULLREF
#define JSON_USE_NULLREF 1
#endif
/// If defined, indicates that the source file is amalgamated /// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion. /// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgamated header. /// Remarks: it is automatically defined in the generated amalgamated header.

View File

@ -193,11 +193,14 @@ public:
// Required for boost integration, e. g. BOOST_TEST // Required for boost integration, e. g. BOOST_TEST
typedef std::string value_type; typedef std::string value_type;
static const Value& null; ///< We regret this reference to a global instance; #if JSON_USE_NULLREF
///< prefer the simpler Value(). // Binary compatibility kludges, do not use.
static const Value& nullRef; ///< just a kludge for binary-compatibility; same static const Value& null;
///< as null static const Value& nullRef;
static Value const& nullSingleton(); ///< Prefer this to null or nullRef. #endif
// null and nullRef are deprecated, use this instead.
static Value const& nullSingleton();
/// 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;

View File

@ -54,7 +54,6 @@ int JSON_API msvc_pre1900_c99_snprintf(char* outBuf,
#define JSON_ASSERT_UNREACHABLE assert(false) #define JSON_ASSERT_UNREACHABLE assert(false)
namespace Json { namespace Json {
template <typename T> template <typename T>
static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) { static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) {
std::unique_ptr<T> r; std::unique_ptr<T> r;
@ -72,10 +71,6 @@ static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) {
#else #else
#define ALIGNAS(byte_alignment) #define ALIGNAS(byte_alignment)
#endif #endif
// static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
// const unsigned char& kNullRef = kNull[0];
// const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
// const Value& Value::nullRef = null;
// static // static
Value const& Value::nullSingleton() { Value const& Value::nullSingleton() {
@ -83,10 +78,15 @@ Value const& Value::nullSingleton() {
return nullStatic; return nullStatic;
} }
#if JSON_USE_NULLREF
// for backwards compatibility, we'll leave these global references around, but // for backwards compatibility, we'll leave these global references around, but
// DO NOT use them in JSONCPP library code any more! // DO NOT use them in JSONCPP library code any more!
// static
Value const& Value::null = Value::nullSingleton(); Value const& Value::null = Value::nullSingleton();
// static
Value const& Value::nullRef = Value::nullSingleton(); Value const& Value::nullRef = Value::nullSingleton();
#endif
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);
@ -1648,20 +1648,20 @@ const Value& Path::resolve(const Value& root) const {
for (const auto& arg : args_) { for (const auto& arg : args_) {
if (arg.kind_ == PathArgument::kindIndex) { if (arg.kind_ == PathArgument::kindIndex) {
if (!node->isArray() || !node->isValidIndex(arg.index_)) { if (!node->isArray() || !node->isValidIndex(arg.index_)) {
// Error: unable to resolve path (array value expected at position... // Error: unable to resolve path (array value expected at position... )
return Value::null; return Value::nullSingleton();
} }
node = &((*node)[arg.index_]); node = &((*node)[arg.index_]);
} else if (arg.kind_ == PathArgument::kindKey) { } else if (arg.kind_ == PathArgument::kindKey) {
if (!node->isObject()) { if (!node->isObject()) {
// Error: unable to resolve path (object value expected at position...) // Error: unable to resolve path (object value expected at position...)
return Value::null; return Value::nullSingleton();
} }
node = &((*node)[arg.key_]); node = &((*node)[arg.key_]);
if (node == &Value::nullSingleton()) { 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...)
return Value::null; return Value::nullSingleton();
} }
} }
} }