Merge pull request #969 from theodelrieu/fix/924

Fix constraints on from_json(CompatibleArrayType)
This commit is contained in:
Niels Lohmann 2018-02-12 18:17:59 +01:00 committed by GitHub
commit 20b5f4d89c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 12 deletions

View file

@ -177,15 +177,21 @@ void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priorit
} }
} }
template<typename BasicJsonType, typename CompatibleArrayType, template <
enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and typename BasicJsonType, typename CompatibleArrayType,
std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and enable_if_t <
not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0> is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
not std::is_same<typename BasicJsonType::array_t,
CompatibleArrayType>::value and
std::is_constructible <
BasicJsonType, typename CompatibleArrayType::value_type >::value,
int > = 0 >
void from_json(const BasicJsonType& j, CompatibleArrayType& arr) void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
{ {
if (JSON_UNLIKELY(not j.is_array())) if (JSON_UNLIKELY(not j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " +
std::string(j.type_name())));
} }
from_json_array_impl(j, arr, priority_tag<2> {}); from_json_array_impl(j, arr, priority_tag<2> {});

View file

@ -1084,15 +1084,21 @@ void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priorit
} }
} }
template<typename BasicJsonType, typename CompatibleArrayType, template <
enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and typename BasicJsonType, typename CompatibleArrayType,
std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and enable_if_t <
not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0> is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
not std::is_same<typename BasicJsonType::array_t,
CompatibleArrayType>::value and
std::is_constructible <
BasicJsonType, typename CompatibleArrayType::value_type >::value,
int > = 0 >
void from_json(const BasicJsonType& j, CompatibleArrayType& arr) void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
{ {
if (JSON_UNLIKELY(not j.is_array())) if (JSON_UNLIKELY(not j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " +
std::string(j.type_name())));
} }
from_json_array_impl(j, arr, priority_tag<2> {}); from_json_array_impl(j, arr, priority_tag<2> {});

View file

@ -711,3 +711,25 @@ TEST_CASE("an incomplete type does not trigger a compiler error in non-evaluated
{ {
static_assert(not is_constructible_patched<json, incomplete>::value, ""); static_assert(not is_constructible_patched<json, incomplete>::value, "");
} }
namespace
{
class Evil
{
public:
Evil() = default;
template <typename T>
Evil(T) {}
};
void from_json(const json&, Evil&) {}
}
TEST_CASE("Issue #924")
{
// Prevent get<std::vector<Evil>>() to throw
auto j = json::array();
(void) j.get<Evil>();
(void) j.get<std::vector<Evil>>();
}