Unverified Commit 9294e25c authored by Niels Lohmann's avatar Niels Lohmann Committed by GitHub

Merge pull request #1301 from theodelrieu/fix/1299

add new is_constructible_* traits used in from_json
parents b553a8a9 a946dfc1
...@@ -84,13 +84,13 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) ...@@ -84,13 +84,13 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
} }
template < template <
typename BasicJsonType, typename CompatibleStringType, typename BasicJsonType, typename ConstructibleStringType,
enable_if_t < enable_if_t <
is_compatible_string_type<BasicJsonType, CompatibleStringType>::value and is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
not std::is_same<typename BasicJsonType::string_t, not std::is_same<typename BasicJsonType::string_t,
CompatibleStringType>::value, ConstructibleStringType>::value,
int > = 0 > int > = 0 >
void from_json(const BasicJsonType& j, CompatibleStringType& s) void from_json(const BasicJsonType& j, ConstructibleStringType& s)
{ {
if (JSON_UNLIKELY(not j.is_string())) if (JSON_UNLIKELY(not j.is_string()))
{ {
...@@ -173,11 +173,11 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, ...@@ -173,11 +173,11 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
} }
} }
template<typename BasicJsonType, typename CompatibleArrayType> template<typename BasicJsonType, typename ConstructibleArrayType>
auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/) auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
-> decltype( -> decltype(
arr.reserve(std::declval<typename CompatibleArrayType::size_type>()), arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
j.template get<typename CompatibleArrayType::value_type>(), j.template get<typename ConstructibleArrayType::value_type>(),
void()) void())
{ {
using std::end; using std::end;
...@@ -188,12 +188,12 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio ...@@ -188,12 +188,12 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
{ {
// get<BasicJsonType>() returns *this, this won't call a from_json // get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType // method when value_type is BasicJsonType
return i.template get<typename CompatibleArrayType::value_type>(); return i.template get<typename ConstructibleArrayType::value_type>();
}); });
} }
template <typename BasicJsonType, typename CompatibleArrayType> template <typename BasicJsonType, typename ConstructibleArrayType>
void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
priority_tag<0> /*unused*/) priority_tag<0> /*unused*/)
{ {
using std::end; using std::end;
...@@ -204,21 +204,21 @@ void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, ...@@ -204,21 +204,21 @@ void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr,
{ {
// get<BasicJsonType>() returns *this, this won't call a from_json // get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType // method when value_type is BasicJsonType
return i.template get<typename CompatibleArrayType::value_type>(); return i.template get<typename ConstructibleArrayType::value_type>();
}); });
} }
template <typename BasicJsonType, typename CompatibleArrayType, template <typename BasicJsonType, typename ConstructibleArrayType,
enable_if_t < enable_if_t <
is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
not is_basic_json<CompatibleArrayType>::value, not is_basic_json<ConstructibleArrayType>::value,
int > = 0 > int > = 0 >
auto from_json(const BasicJsonType& j, CompatibleArrayType& arr) auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
j.template get<typename CompatibleArrayType::value_type>(), j.template get<typename ConstructibleArrayType::value_type>(),
void()) void())
{ {
if (JSON_UNLIKELY(not j.is_array())) if (JSON_UNLIKELY(not j.is_array()))
...@@ -230,9 +230,9 @@ void()) ...@@ -230,9 +230,9 @@ void())
from_json_array_impl(j, arr, priority_tag<3> {}); from_json_array_impl(j, arr, priority_tag<3> {});
} }
template<typename BasicJsonType, typename CompatibleObjectType, template<typename BasicJsonType, typename ConstructibleObjectType,
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0> enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
void from_json(const BasicJsonType& j, CompatibleObjectType& obj) void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
{ {
if (JSON_UNLIKELY(not j.is_object())) if (JSON_UNLIKELY(not j.is_object()))
{ {
...@@ -240,13 +240,13 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj) ...@@ -240,13 +240,13 @@ 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 value_type = typename CompatibleObjectType::value_type; using value_type = typename ConstructibleObjectType::value_type;
std::transform( std::transform(
inner_object->begin(), inner_object->end(), inner_object->begin(), inner_object->end(),
std::inserter(obj, obj.begin()), std::inserter(obj, obj.begin()),
[](typename BasicJsonType::object_t::value_type const & p) [](typename BasicJsonType::object_t::value_type const & p)
{ {
return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>()); return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
}); });
} }
......
This diff is collapsed.
...@@ -121,6 +121,28 @@ struct nocopy ...@@ -121,6 +121,28 @@ struct nocopy
j = {{"val", n.val}}; j = {{"val", n.val}};
} }
}; };
struct Data
{
std::string a;
std::string b;
};
void from_json(const json& j, Data& data)
{
j["a"].get_to(data.a);
j["b"].get_to(data.b);
}
bool operator==(Data const& lhs, Data const& rhs)
{
return lhs.a == rhs.a && lhs.b == rhs.b;
}
bool operator!=(Data const& lhs, Data const& rhs)
{
return !(lhs == rhs);
}
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
...@@ -1665,4 +1687,24 @@ TEST_CASE("regression tests") ...@@ -1665,4 +1687,24 @@ TEST_CASE("regression tests")
not std::is_constructible<json, std::variant<int, float>>::value, ""); not std::is_constructible<json, std::variant<int, float>>::value, "");
} }
#endif #endif
SECTION("issue #1299 - compile error in from_json converting to container "
"with std::pair")
{
json j =
{
{"1", {{"a", "testa_1"}, {"b", "testb_1"}}},
{"2", {{"a", "testa_2"}, {"b", "testb_2"}}},
{"3", {{"a", "testa_3"}, {"b", "testb_3"}}},
};
std::map<std::string, Data> expected
{
{"1", {"testa_1", "testb_1" }},
{"2", {"testa_2", "testb_2"}},
{"3", {"testa_3", "testb_3"}},
};
const auto data = j.get<decltype(expected)>();
CHECK(expected == data);
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment