mirror of
https://github.com/nlohmann/json
synced 2025-01-15 03:30:04 +00:00
🚧 better diagnostics
This commit is contained in:
parent
68c3696382
commit
a4d491e22d
@ -1642,6 +1642,9 @@ class basic_json
|
|||||||
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
||||||
{
|
{
|
||||||
auto element = element_ref.moved_or_copied();
|
auto element = element_ref.moved_or_copied();
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
(*element.m_value.array)[1].m_parent = this;
|
||||||
|
#endif
|
||||||
m_value.object->emplace(
|
m_value.object->emplace(
|
||||||
std::move(*((*element.m_value.array)[0].m_value.string)),
|
std::move(*((*element.m_value.array)[0].m_value.string)),
|
||||||
std::move((*element.m_value.array)[1]));
|
std::move((*element.m_value.array)[1]));
|
||||||
@ -1652,6 +1655,12 @@ class basic_json
|
|||||||
// the initializer list describes an array -> create array
|
// the initializer list describes an array -> create array
|
||||||
m_type = value_t::array;
|
m_type = value_t::array;
|
||||||
m_value.array = create<array_t>(init.begin(), init.end());
|
m_value.array = create<array_t>(init.begin(), init.end());
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
for (auto& element : *m_value.array)
|
||||||
|
{
|
||||||
|
element.m_parent = this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_invariant();
|
assert_invariant();
|
||||||
@ -2696,6 +2705,49 @@ class basic_json
|
|||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
std::string diagnostics()
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
for (basic_json* current = this; current->m_parent != nullptr; current = current->m_parent)
|
||||||
|
{
|
||||||
|
switch (current->m_parent->type())
|
||||||
|
{
|
||||||
|
case value_t::array:
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
|
||||||
|
{
|
||||||
|
if (current->m_parent->m_value.array->operator[](i) == *current)
|
||||||
|
{
|
||||||
|
result = "/" + std::to_string(i) + result;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::object:
|
||||||
|
{
|
||||||
|
for (auto it : *current->m_parent->m_value.object)
|
||||||
|
{
|
||||||
|
if (it.second == *current)
|
||||||
|
{
|
||||||
|
result = "/" + it.first + result;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// value access //
|
// value access //
|
||||||
//////////////////
|
//////////////////
|
||||||
@ -3318,7 +3370,13 @@ class basic_json
|
|||||||
{
|
{
|
||||||
JSON_TRY
|
JSON_TRY
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.array->at(idx);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.array->at(idx);
|
return m_value.array->at(idx);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
JSON_CATCH (std::out_of_range&)
|
JSON_CATCH (std::out_of_range&)
|
||||||
{
|
{
|
||||||
@ -3416,7 +3474,13 @@ class basic_json
|
|||||||
{
|
{
|
||||||
JSON_TRY
|
JSON_TRY
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.object->at(key);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.object->at(key);
|
return m_value.object->at(key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
JSON_CATCH (std::out_of_range&)
|
JSON_CATCH (std::out_of_range&)
|
||||||
{
|
{
|
||||||
@ -3525,9 +3589,18 @@ class basic_json
|
|||||||
m_value.array->insert(m_value.array->end(),
|
m_value.array->insert(m_value.array->end(),
|
||||||
idx - m_value.array->size() + 1,
|
idx - m_value.array->size() + 1,
|
||||||
basic_json());
|
basic_json());
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.array->operator[](idx);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.array->operator[](idx);
|
return m_value.array->operator[](idx);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||||
@ -3603,7 +3676,13 @@ class basic_json
|
|||||||
// operator[] only works for objects
|
// operator[] only works for objects
|
||||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.object->operator[](key);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.object->operator[](key);
|
return m_value.object->operator[](key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||||
@ -3693,7 +3772,13 @@ class basic_json
|
|||||||
// at only works for objects
|
// at only works for objects
|
||||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.object->operator[](key);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.object->operator[](key);
|
return m_value.object->operator[](key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||||
@ -5249,6 +5334,9 @@ class basic_json
|
|||||||
|
|
||||||
// add element to array (move semantics)
|
// add element to array (move semantics)
|
||||||
m_value.array->push_back(std::move(val));
|
m_value.array->push_back(std::move(val));
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
|
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5284,6 +5372,9 @@ class basic_json
|
|||||||
|
|
||||||
// add element to array
|
// add element to array
|
||||||
m_value.array->push_back(val);
|
m_value.array->push_back(val);
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -5332,8 +5423,13 @@ class basic_json
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
// add element to array
|
// add element to object
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
auto res = m_value.object->insert(val);
|
||||||
|
res.first->second.m_parent = this;
|
||||||
|
#else
|
||||||
m_value.object->insert(val);
|
m_value.object->insert(val);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -5437,9 +5533,18 @@ class basic_json
|
|||||||
|
|
||||||
// add element to array (perfect forwarding)
|
// add element to array (perfect forwarding)
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.array->emplace_back(std::forward<Args>(args)...);
|
return m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
m_value.array->emplace_back(std::forward<Args>(args)...);
|
m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
return m_value.array->back();
|
return m_value.array->back();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -6967,6 +7072,11 @@ class basic_json
|
|||||||
/// the value of the current element
|
/// the value of the current element
|
||||||
json_value m_value = {};
|
json_value m_value = {};
|
||||||
|
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
/// a pointer to a parent value (for debugging purposes)
|
||||||
|
basic_json* m_parent = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
// binary serialization/deserialization //
|
// binary serialization/deserialization //
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
@ -18266,6 +18266,9 @@ class basic_json
|
|||||||
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
||||||
{
|
{
|
||||||
auto element = element_ref.moved_or_copied();
|
auto element = element_ref.moved_or_copied();
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
(*element.m_value.array)[1].m_parent = this;
|
||||||
|
#endif
|
||||||
m_value.object->emplace(
|
m_value.object->emplace(
|
||||||
std::move(*((*element.m_value.array)[0].m_value.string)),
|
std::move(*((*element.m_value.array)[0].m_value.string)),
|
||||||
std::move((*element.m_value.array)[1]));
|
std::move((*element.m_value.array)[1]));
|
||||||
@ -18276,6 +18279,12 @@ class basic_json
|
|||||||
// the initializer list describes an array -> create array
|
// the initializer list describes an array -> create array
|
||||||
m_type = value_t::array;
|
m_type = value_t::array;
|
||||||
m_value.array = create<array_t>(init.begin(), init.end());
|
m_value.array = create<array_t>(init.begin(), init.end());
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
for (auto& element : *m_value.array)
|
||||||
|
{
|
||||||
|
element.m_parent = this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_invariant();
|
assert_invariant();
|
||||||
@ -19320,6 +19329,49 @@ class basic_json
|
|||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
std::string diagnostics()
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
for (basic_json* current = this; current->m_parent != nullptr; current = current->m_parent)
|
||||||
|
{
|
||||||
|
switch (current->m_parent->type())
|
||||||
|
{
|
||||||
|
case value_t::array:
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
|
||||||
|
{
|
||||||
|
if (current->m_parent->m_value.array->operator[](i) == *current)
|
||||||
|
{
|
||||||
|
result = "/" + std::to_string(i) + result;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::object:
|
||||||
|
{
|
||||||
|
for (auto it : *current->m_parent->m_value.object)
|
||||||
|
{
|
||||||
|
if (it.second == *current)
|
||||||
|
{
|
||||||
|
result = "/" + it.first + result;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// value access //
|
// value access //
|
||||||
//////////////////
|
//////////////////
|
||||||
@ -19942,7 +19994,13 @@ class basic_json
|
|||||||
{
|
{
|
||||||
JSON_TRY
|
JSON_TRY
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.array->at(idx);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.array->at(idx);
|
return m_value.array->at(idx);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
JSON_CATCH (std::out_of_range&)
|
JSON_CATCH (std::out_of_range&)
|
||||||
{
|
{
|
||||||
@ -20040,7 +20098,13 @@ class basic_json
|
|||||||
{
|
{
|
||||||
JSON_TRY
|
JSON_TRY
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.object->at(key);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.object->at(key);
|
return m_value.object->at(key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
JSON_CATCH (std::out_of_range&)
|
JSON_CATCH (std::out_of_range&)
|
||||||
{
|
{
|
||||||
@ -20149,9 +20213,18 @@ class basic_json
|
|||||||
m_value.array->insert(m_value.array->end(),
|
m_value.array->insert(m_value.array->end(),
|
||||||
idx - m_value.array->size() + 1,
|
idx - m_value.array->size() + 1,
|
||||||
basic_json());
|
basic_json());
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.array->operator[](idx);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.array->operator[](idx);
|
return m_value.array->operator[](idx);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||||
@ -20227,7 +20300,13 @@ class basic_json
|
|||||||
// operator[] only works for objects
|
// operator[] only works for objects
|
||||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.object->operator[](key);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.object->operator[](key);
|
return m_value.object->operator[](key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||||
@ -20317,7 +20396,13 @@ class basic_json
|
|||||||
// at only works for objects
|
// at only works for objects
|
||||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||||
{
|
{
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.object->operator[](key);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.object->operator[](key);
|
return m_value.object->operator[](key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||||
@ -21873,6 +21958,9 @@ class basic_json
|
|||||||
|
|
||||||
// add element to array (move semantics)
|
// add element to array (move semantics)
|
||||||
m_value.array->push_back(std::move(val));
|
m_value.array->push_back(std::move(val));
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
|
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21908,6 +21996,9 @@ class basic_json
|
|||||||
|
|
||||||
// add element to array
|
// add element to array
|
||||||
m_value.array->push_back(val);
|
m_value.array->push_back(val);
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -21956,8 +22047,13 @@ class basic_json
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
// add element to array
|
// add element to object
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
auto res = m_value.object->insert(val);
|
||||||
|
res.first->second.m_parent = this;
|
||||||
|
#else
|
||||||
m_value.object->insert(val);
|
m_value.object->insert(val);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -22061,9 +22157,18 @@ class basic_json
|
|||||||
|
|
||||||
// add element to array (perfect forwarding)
|
// add element to array (perfect forwarding)
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
reference result = m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||||
|
result.m_parent = this;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
return m_value.array->emplace_back(std::forward<Args>(args)...);
|
return m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
m_value.array->emplace_back(std::forward<Args>(args)...);
|
m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
m_value.array->back().m_parent = this;
|
||||||
|
#endif
|
||||||
return m_value.array->back();
|
return m_value.array->back();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -23591,6 +23696,11 @@ class basic_json
|
|||||||
/// the value of the current element
|
/// the value of the current element
|
||||||
json_value m_value = {};
|
json_value m_value = {};
|
||||||
|
|
||||||
|
#ifdef JSON_DIAGNOSTICS
|
||||||
|
/// a pointer to a parent value (for debugging purposes)
|
||||||
|
basic_json* m_parent = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
// binary serialization/deserialization //
|
// binary serialization/deserialization //
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user