Merge pull request #969 from theodelrieu/fix/924
Fix constraints on from_json(CompatibleArrayType)
diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp
index 8ea0284..eccc04f 100644
--- a/include/nlohmann/detail/conversions/from_json.hpp
+++ b/include/nlohmann/detail/conversions/from_json.hpp
@@ -177,15 +177,21 @@
}
}
-template<typename BasicJsonType, typename CompatibleArrayType,
- enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
- std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
- not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
+template <
+ typename BasicJsonType, typename CompatibleArrayType,
+ enable_if_t <
+ 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)
{
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> {});
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index a7c009c..c753058 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -1084,15 +1084,21 @@
}
}
-template<typename BasicJsonType, typename CompatibleArrayType,
- enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
- std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
- not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
+template <
+ typename BasicJsonType, typename CompatibleArrayType,
+ enable_if_t <
+ 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)
{
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> {});
diff --git a/test/src/unit-inspection.cpp b/test/src/unit-inspection.cpp
index 5facb11..4bee80d 100644
--- a/test/src/unit-inspection.cpp
+++ b/test/src/unit-inspection.cpp
@@ -316,8 +316,8 @@
SECTION("round trips")
{
for (const auto& s :
- {"3.141592653589793", "1000000000000000010E5"
- })
+ {"3.141592653589793", "1000000000000000010E5"
+ })
{
json j1 = json::parse(s);
std::string s1 = j1.dump();
diff --git a/test/src/unit-udt.cpp b/test/src/unit-udt.cpp
index 17baf4e..65ca788 100644
--- a/test/src/unit-udt.cpp
+++ b/test/src/unit-udt.cpp
@@ -711,3 +711,25 @@
{
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>>();
+}