CHG: explicit size checks and more expressive exceptions for converstion of fixed size containers from json

MNT: updated amalgamation header
This commit is contained in:
domsoll 2020-12-29 18:42:19 +01:00
parent db78ac1d77
commit ba239535a3
2 changed files with 66 additions and 2 deletions

View File

@ -164,6 +164,14 @@ template<typename BasicJsonType, typename T, std::size_t N>
auto from_json(const BasicJsonType& j, T (&arr)[N]) auto from_json(const BasicJsonType& j, T (&arr)[N])
-> decltype(j.template get<T>(), void()) -> decltype(j.template get<T>(), void())
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != N))
{
JSON_THROW(type_error::create(302, "array size must be " + std::to_string(N) + ", but is " + std::to_string(j.size())));
}
for (std::size_t i = 0; i < N; ++i) for (std::size_t i = 0; i < N; ++i)
{ {
arr[i] = j.at(i).template get<T>(); arr[i] = j.at(i).template get<T>();
@ -181,6 +189,14 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
priority_tag<2> /*unused*/) priority_tag<2> /*unused*/)
-> decltype(j.template get<T>(), void()) -> decltype(j.template get<T>(), void())
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != N))
{
JSON_THROW(type_error::create(302, "array size must be " + std::to_string(N) + ", but is " + std::to_string(j.size())));
}
for (std::size_t i = 0; i < N; ++i) for (std::size_t i = 0; i < N; ++i)
{ {
arr[i] = j.at(i).template get<T>(); arr[i] = j.at(i).template get<T>();
@ -326,12 +342,28 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
template<typename BasicJsonType, typename A1, typename A2> template<typename BasicJsonType, typename A1, typename A2>
void from_json(const BasicJsonType& j, std::pair<A1, A2>& p) void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != 2))
{
JSON_THROW(type_error::create(302, "array size must be 2, but is " + std::to_string(j.size())));
}
p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()}; p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
} }
template<typename BasicJsonType, typename Tuple, std::size_t... Idx> template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/) void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != sizeof...(Idx)))
{
JSON_THROW(type_error::create(302, "array size must be " + std::to_string(sizeof...(Idx)) + ", but is " + std::to_string(j.size())));
}
t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...); t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
} }

View File

@ -3564,6 +3564,14 @@ template<typename BasicJsonType, typename T, std::size_t N>
auto from_json(const BasicJsonType& j, T (&arr)[N]) auto from_json(const BasicJsonType& j, T (&arr)[N])
-> decltype(j.template get<T>(), void()) -> decltype(j.template get<T>(), void())
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != N))
{
JSON_THROW(type_error::create(302, "array size must be " + std::to_string(N) + ", but is " + std::to_string(j.size())));
}
for (std::size_t i = 0; i < N; ++i) for (std::size_t i = 0; i < N; ++i)
{ {
arr[i] = j.at(i).template get<T>(); arr[i] = j.at(i).template get<T>();
@ -3581,6 +3589,14 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
priority_tag<2> /*unused*/) priority_tag<2> /*unused*/)
-> decltype(j.template get<T>(), void()) -> decltype(j.template get<T>(), void())
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != N))
{
JSON_THROW(type_error::create(302, "array size must be " + std::to_string(N) + ", but is " + std::to_string(j.size())));
}
for (std::size_t i = 0; i < N; ++i) for (std::size_t i = 0; i < N; ++i)
{ {
arr[i] = j.at(i).template get<T>(); arr[i] = j.at(i).template get<T>();
@ -3726,12 +3742,28 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
template<typename BasicJsonType, typename A1, typename A2> template<typename BasicJsonType, typename A1, typename A2>
void from_json(const BasicJsonType& j, std::pair<A1, A2>& p) void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != 2))
{
JSON_THROW(type_error::create(302, "array size must be 2, but is " + std::to_string(j.size())));
}
p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()}; p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
} }
template<typename BasicJsonType, typename Tuple, std::size_t... Idx> template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/) void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
{ {
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
}
if (JSON_HEDLEY_UNLIKELY(j.size() != sizeof...(Idx)))
{
JSON_THROW(type_error::create(302, "array size must be " + std::to_string(sizeof...(Idx)) + ", but is " + std::to_string(j.size())));
}
t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...); t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
} }
@ -16686,7 +16718,7 @@ class basic_json
detail::parser_callback_t<basic_json>cb = nullptr, detail::parser_callback_t<basic_json>cb = nullptr,
const bool allow_exceptions = true, const bool allow_exceptions = true,
const bool ignore_comments = false const bool ignore_comments = false
) )
{ {
return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
std::move(cb), allow_exceptions, ignore_comments); std::move(cb), allow_exceptions, ignore_comments);
@ -25227,7 +25259,7 @@ template<>
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
is_nothrow_move_constructible<nlohmann::json>::value&& is_nothrow_move_constructible<nlohmann::json>::value&&
is_nothrow_move_assignable<nlohmann::json>::value is_nothrow_move_assignable<nlohmann::json>::value
) )
{ {
j1.swap(j2); j1.swap(j2);
} }