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

🐛 fix assertion failure #2838

This commit is contained in:
Niels Lohmann
2021-07-12 13:38:28 +02:00
parent 9426074ce8
commit d40e98ecef
3 changed files with 157 additions and 22 deletions

View File

@ -22406,8 +22406,18 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// add element to array (move semantics)
const auto capacity = m_value.array->capacity();
m_value.array->push_back(std::move(val));
set_parent(m_value.array->back());
if (capacity == m_value.array->capacity())
{
// capacity has not changed: updating parent of last element is sufficient
set_parent(m_value.array->back());
}
else
{
// capacity has changed: update all elements' parents
set_parents();
}
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
}
@ -22442,7 +22452,18 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// add element to array
const auto capacity = m_value.array->capacity();
m_value.array->push_back(val);
if (capacity == m_value.array->capacity())
{
// capacity has not changed: updating parent of last element is sufficient
set_parent(m_value.array->back());
}
else
{
// capacity has changed: update all elements' parents
set_parents();
}
set_parent(m_value.array->back());
}
@ -22597,12 +22618,18 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// add element to array (perfect forwarding)
#ifdef JSON_HAS_CPP_17
return set_parent(m_value.array->emplace_back(std::forward<Args>(args)...));
#else
const auto capacity = m_value.array->capacity();
m_value.array->emplace_back(std::forward<Args>(args)...);
return set_parent(m_value.array->back());
#endif
if (capacity == m_value.array->capacity())
{
// capacity has not changed: updating parent of last element is sufficient
return set_parent(m_value.array->back());
}
// capacity has changed: update all elements' parents
set_parents();
return m_value.array->back();
}
/*!
@ -22665,12 +22692,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
/// @note: This uses std::distance to support GCC 4.8,
/// see https://github.com/nlohmann/json/pull/1257
template<typename... Args>
iterator insert_iterator(const_iterator pos, Args&& ... args)
iterator insert_iterator(const_iterator pos, typename iterator::difference_type cnt, Args&& ... args)
{
iterator result(this);
JSON_ASSERT(m_value.array != nullptr);
auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
const auto capacity = m_value.array->capacity();
m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
result.m_it.array_iterator = m_value.array->begin() + insert_pos;
@ -22678,6 +22706,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
// but the return value of insert is missing in GCC 4.8, so it is written this way instead.
if (capacity == m_value.array->capacity())
{
// capacity has not changed: updating parent of inserted elements is sufficient
set_parents(result, cnt);
}
else
{
// capacity has changed: update all elements' parents
set_parents();
}
return result;
}
@ -22715,7 +22754,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// insert to array and return iterator
return set_parents(insert_iterator(pos, val), static_cast<typename iterator::difference_type>(1));
return insert_iterator(pos, static_cast<typename iterator::difference_type>(1), val);
}
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
@ -22766,7 +22805,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// insert to array and return iterator
return set_parents(insert_iterator(pos, cnt, val), static_cast<typename iterator::difference_type>(cnt));
return insert_iterator(pos, static_cast<typename iterator::difference_type>(cnt), cnt, val);
}
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
@ -22828,7 +22867,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// insert to array and return iterator
return set_parents(insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator), std::distance(first, last));
return insert_iterator(pos, std::distance(first, last), first.m_it.array_iterator, last.m_it.array_iterator);
}
/*!
@ -22870,7 +22909,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// insert to array and return iterator
return set_parents(insert_iterator(pos, ilist.begin(), ilist.end()), static_cast<typename iterator::difference_type>(ilist.size()));
return insert_iterator(pos, static_cast<typename iterator::difference_type>(ilist.size()), ilist.begin(), ilist.end());
}
/*!