1
0
mirror of https://github.com/nlohmann/json.git synced 2025-07-28 12:02:00 +03:00

Add recursive update function (#3069)

*  add recursive update function
This commit is contained in:
Niels Lohmann
2021-11-03 13:52:20 +01:00
committed by GitHub
parent 7440786b81
commit 5d87c4d409
9 changed files with 243 additions and 128 deletions

View File

@ -5954,6 +5954,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
Inserts all values from JSON object @a j and overwrites existing keys.
@param[in] j JSON object to read values from
@param[in] merge_objects when true, existing keys are not overwritten, but
contents of objects are merged recursively
(default: false)
@throw type_error.312 if called on JSON values other than objects; example:
`"cannot use update() with string"`
@ -5965,34 +5968,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
@since version 3.0.0
@since version 3.0.0, `merge_objects` parameter added in 3.10.4.
*/
void update(const_reference j)
void update(const_reference j, bool merge_objects = false)
{
// implicitly convert null value to an empty object
if (is_null())
{
m_type = value_t::object;
m_value.object = create<object_t>();
assert_invariant();
}
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
}
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
{
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
}
for (auto it = j.cbegin(); it != j.cend(); ++it)
{
m_value.object->operator[](it.key()) = it.value();
#if JSON_DIAGNOSTICS
m_value.object->operator[](it.key()).m_parent = this;
#endif
}
update(j.begin(), j.end(), merge_objects);
}
/*!
@ -6003,12 +5983,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@param[in] first begin of the range of elements to insert
@param[in] last end of the range of elements to insert
@param[in] merge_objects when true, existing keys are not overwritten, but
contents of objects are merged recursively
(default: false)
@throw type_error.312 if called on JSON values other than objects; example:
`"cannot use update() with string"`
@throw invalid_iterator.202 if iterator @a first or @a last does does not
point to an object; example: `"iterators first and last must point to
objects"`
@throw type_error.312 if iterator @a first or @a last does does not
point to an object; example: `"cannot use update() with string"`
@throw invalid_iterator.210 if @a first and @a last do not belong to the
same JSON value; example: `"iterators do not fit"`
@ -6019,9 +6001,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
@since version 3.0.0
@since version 3.0.0, `merge_objects` parameter added in 3.10.4.
*/
void update(const_iterator first, const_iterator last)
void update(const_iterator first, const_iterator last, bool merge_objects = false)
{
// implicitly convert null value to an empty object
if (is_null())
@ -6043,14 +6025,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// passed iterators must belong to objects
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
|| !last.m_object->is_object()))
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(first.m_object->type_name()), *first.m_object));
}
for (auto it = first; it != last; ++it)
{
if (merge_objects && it.value().is_object())
{
auto it2 = m_value.object->find(it.key());
if (it2 != m_value.object->end())
{
it2->second.update(it.value(), true);
continue;
}
}
m_value.object->operator[](it.key()) = it.value();
#if JSON_DIAGNOSTICS
m_value.object->operator[](it.key()).m_parent = this;