Instead of calling CompatibleObjectType iterator-range constructor,
first convert json::value_type to CompatibleObjectType::value_type
This commit is contained in:
Théo DELRIEU 2017-06-06 14:18:32 +02:00
parent 85de93ba93
commit cea39dfaa8
No known key found for this signature in database
GPG key ID: C64D5E244E08ADC6
2 changed files with 56 additions and 20 deletions

View file

@ -1046,10 +1046,24 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>(); auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
using std::begin; using std::begin;
using std::end; using std::end;
using value_type = typename CompatibleObjectType::value_type;
std::vector<value_type> v;
v.reserve(j.size());
std::transform(
inner_object->begin(), inner_object->end(), std::back_inserter(v),
[](typename BasicJsonType::object_t::value_type const & p)
{
return value_type
{
p.first,
p.second
.template get<typename CompatibleObjectType::mapped_type>()};
});
// we could avoid the assignment, but this might require a for loop, which // we could avoid the assignment, but this might require a for loop, which
// might be less efficient than the container constructor for some // might be less efficient than the container constructor for some
// containers (would it?) // containers (would it?)
obj = CompatibleObjectType(begin(*inner_object), end(*inner_object)); obj = CompatibleObjectType(std::make_move_iterator(begin(v)),
std::make_move_iterator(end(v)));
} }
// overload for arithmetic types, not chosen for basic_json template arguments // overload for arithmetic types, not chosen for basic_json template arguments

View file

@ -170,6 +170,17 @@ TEST_CASE("constructors")
CHECK((j2.get<decltype(p2)>() == p2)); CHECK((j2.get<decltype(p2)>() == p2));
} }
SECTION("std::map<std::string, std::string> #600")
{
std::map<std::string, std::string> m;
m["a"] = "b";
m["c"] = "d";
m["e"] = "f";
json j(m);
CHECK((j.get<decltype(m)>() == m));
}
SECTION("std::map<const char*, json>") SECTION("std::map<const char*, json>")
{ {
std::map<const char*, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; std::map<const char*, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
@ -970,6 +981,8 @@ TEST_CASE("constructors")
} }
SECTION("std::pair<CompatibleString, T> with error") SECTION("std::pair<CompatibleString, T> with error")
{
SECTION("wrong field number")
{ {
json j{{"too", "much"}, {"string", "fields"}}; json j{{"too", "much"}, {"string", "fields"}};
CHECK_THROWS_AS((j.get<std::pair<std::string, std::string>>()), json::other_error); CHECK_THROWS_AS((j.get<std::pair<std::string, std::string>>()), json::other_error);
@ -979,6 +992,15 @@ TEST_CASE("constructors")
"exactly one field, but it has 2"); "exactly one field, but it has 2");
} }
SECTION("wrong JSON type")
{
json j(42);
CHECK_THROWS_AS((j.get<std::pair<std::string, std::string>>()), json::type_error);
CHECK_THROWS_WITH((j.get<std::pair<std::string, std::string>>()),
"[json.exception.type_error.302] type must be object, but is number");
}
}
SECTION("empty array") SECTION("empty array")
{ {