mirror of
https://github.com/nlohmann/json.git
synced 2026-09-06 00:08:00 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e29ac4f043 |
@@ -398,6 +398,34 @@ inline void from_json(const BasicJsonType& j, CompatibleArrayType& bin)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename ConstructibleObjectType>
|
||||
auto from_json_object_impl(const BasicJsonType& j, ConstructibleObjectType& obj, priority_tag<1> /*unused*/)
|
||||
-> decltype(
|
||||
obj.reserve(std::declval<typename ConstructibleObjectType::size_type>()),
|
||||
void())
|
||||
{
|
||||
ConstructibleObjectType ret;
|
||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||
ret.reserve(inner_object->size());
|
||||
for (const auto& p : *inner_object)
|
||||
{
|
||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||
}
|
||||
obj = std::move(ret);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename ConstructibleObjectType>
|
||||
inline void from_json_object_impl(const BasicJsonType& j, ConstructibleObjectType& obj, priority_tag<0> /*unused*/)
|
||||
{
|
||||
ConstructibleObjectType ret;
|
||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||
for (const auto& p : *inner_object)
|
||||
{
|
||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||
}
|
||||
obj = std::move(ret);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename ConstructibleObjectType,
|
||||
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
|
||||
inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||
@@ -407,13 +435,7 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||
JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
|
||||
}
|
||||
|
||||
ConstructibleObjectType ret;
|
||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||
for (const auto& p : *inner_object)
|
||||
{
|
||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||
}
|
||||
obj = std::move(ret);
|
||||
from_json_object_impl(j, obj, priority_tag<1> {});
|
||||
}
|
||||
|
||||
// overload for arithmetic types, not chosen for basic_json template arguments
|
||||
|
||||
@@ -5693,6 +5693,34 @@ inline void from_json(const BasicJsonType& j, CompatibleArrayType& bin)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename ConstructibleObjectType>
|
||||
auto from_json_object_impl(const BasicJsonType& j, ConstructibleObjectType& obj, priority_tag<1> /*unused*/)
|
||||
-> decltype(
|
||||
obj.reserve(std::declval<typename ConstructibleObjectType::size_type>()),
|
||||
void())
|
||||
{
|
||||
ConstructibleObjectType ret;
|
||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||
ret.reserve(inner_object->size());
|
||||
for (const auto& p : *inner_object)
|
||||
{
|
||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||
}
|
||||
obj = std::move(ret);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename ConstructibleObjectType>
|
||||
inline void from_json_object_impl(const BasicJsonType& j, ConstructibleObjectType& obj, priority_tag<0> /*unused*/)
|
||||
{
|
||||
ConstructibleObjectType ret;
|
||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||
for (const auto& p : *inner_object)
|
||||
{
|
||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||
}
|
||||
obj = std::move(ret);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename ConstructibleObjectType,
|
||||
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
|
||||
inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||
@@ -5702,13 +5730,7 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||
JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
|
||||
}
|
||||
|
||||
ConstructibleObjectType ret;
|
||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||
for (const auto& p : *inner_object)
|
||||
{
|
||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||
}
|
||||
obj = std::move(ret);
|
||||
from_json_object_impl(j, obj, priority_tag<1> {});
|
||||
}
|
||||
|
||||
// overload for arithmetic types, not chosen for basic_json template arguments
|
||||
|
||||
@@ -1389,6 +1389,37 @@ TEST_CASE("value conversion")
|
||||
// CHECK(m5["one"] == "eins");
|
||||
}
|
||||
|
||||
SECTION("reserve is called on containers that support it (#5406)")
|
||||
{
|
||||
// build a larger object so that a missing/incorrect reserve()
|
||||
// call would be more likely to corrupt or drop elements
|
||||
json j_large;
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
j_large[std::to_string(i)] = i;
|
||||
}
|
||||
|
||||
SECTION("std::unordered_map (supports reserve)")
|
||||
{
|
||||
const auto m = j_large.get<std::unordered_map<std::string, int>>();
|
||||
CHECK(m.size() == 100);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
CHECK(m.at(std::to_string(i)) == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::map (no reserve, fallback path)")
|
||||
{
|
||||
const auto m = j_large.get<std::map<std::string, int>>();
|
||||
CHECK(m.size() == 100);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
CHECK(m.at(std::to_string(i)) == i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::multimap")
|
||||
{
|
||||
j1.get<std::multimap<std::string, int>>();
|
||||
|
||||
Reference in New Issue
Block a user