mirror of
https://github.com/nlohmann/json.git
synced 2026-09-14 20:27:58 +00:00
Merge remote-tracking branch 'origin/develop' into HEAD
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm> // min
|
||||
#include <cstddef>
|
||||
#include <string> // string
|
||||
#include <type_traits> // enable_if_t
|
||||
@@ -17,6 +18,7 @@
|
||||
#include <nlohmann/detail/exceptions.hpp>
|
||||
#include <nlohmann/detail/input/lexer.hpp>
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||
#include <nlohmann/detail/string_concat.hpp>
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
@@ -150,6 +152,29 @@ constexpr std::size_t unknown_size()
|
||||
return (std::numeric_limits<std::size_t>::max)();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief reserve capacity for @a len elements in array @a arr
|
||||
|
||||
Reserving upfront avoids repeated reallocations while the elements are added,
|
||||
but the reservation is capped so a bogus/hostile length (which is not bounded
|
||||
by max_size(), unlike e.g. std::vector) cannot trigger an oversized allocation
|
||||
for a small or truncated input.
|
||||
|
||||
The overload below is selected for array types without reserve() (e.g.,
|
||||
std::deque), which are then left untouched.
|
||||
*/
|
||||
template<typename ArrayType>
|
||||
auto reserve_array(ArrayType& arr, std::size_t len, priority_tag<1> /*unused*/)
|
||||
-> decltype(arr.reserve(len), void())
|
||||
{
|
||||
constexpr std::size_t reserve_cap = 16384;
|
||||
arr.reserve((std::min)(len, reserve_cap));
|
||||
}
|
||||
|
||||
template<typename ArrayType>
|
||||
inline void reserve_array(ArrayType& /*arr*/, std::size_t /*len*/, priority_tag<0> /*unused*/)
|
||||
{}
|
||||
|
||||
/*!
|
||||
@brief SAX implementation to create a JSON value from SAX events
|
||||
|
||||
@@ -305,6 +330,11 @@ class json_sax_dom_parser
|
||||
JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
|
||||
}
|
||||
|
||||
if (len != detail::unknown_size())
|
||||
{
|
||||
reserve_array(*ref_stack.back()->m_data.m_value.array, len, priority_tag<1> {});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -683,6 +713,11 @@ class json_sax_dom_callback_parser
|
||||
{
|
||||
JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
|
||||
}
|
||||
|
||||
if (len != detail::unknown_size())
|
||||
{
|
||||
reserve_array(*ref_stack.back()->m_data.m_value.array, len, priority_tag<1> {});
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -3576,6 +3576,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
std::swap(m_data.m_type, other.m_data.m_type);
|
||||
std::swap(m_data.m_value, other.m_data.m_value);
|
||||
|
||||
#if JSON_DIAGNOSTIC_POSITIONS
|
||||
std::swap(start_position, other.start_position);
|
||||
std::swap(end_position, other.end_position);
|
||||
#endif
|
||||
|
||||
set_parents();
|
||||
other.set_parents();
|
||||
assert_invariant();
|
||||
|
||||
Reference in New Issue
Block a user