diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index 5956352f..15215d6e 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -127,16 +127,6 @@ void from_json(const BasicJsonType& j, EnumType& e) e = static_cast(val); } -template -void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& 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()))); - } - arr = *j.template get_ptr(); -} - // forward_list doesn't have an insert method template::value, int> = 0> @@ -166,24 +156,28 @@ void from_json(const BasicJsonType& j, std::valarray& l) std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l)); } -template -void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/) +template +void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) { - using std::end; + arr = *j.template get_ptr(); +} - std::transform(j.begin(), j.end(), - std::inserter(arr, end(arr)), [](const BasicJsonType & i) +template +auto from_json_array_impl(const BasicJsonType& j, std::array& arr, + priority_tag<2> /*unused*/) +-> decltype(j.template get(), void()) +{ + for (std::size_t i = 0; i < N; ++i) { - // get() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get(); - }); + arr[i] = j.at(i).template get(); + } } template auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/) -> decltype( arr.reserve(std::declval()), + j.template get(), void()) { using std::end; @@ -198,25 +192,34 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio }); } -template -void from_json_array_impl(const BasicJsonType& j, std::array& arr, priority_tag<2> /*unused*/) +template +void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, + priority_tag<0> /*unused*/) { - for (std::size_t i = 0; i < N; ++i) + using std::end; + + std::transform( + j.begin(), j.end(), std::inserter(arr, end(arr)), + [](const BasicJsonType & i) { - arr[i] = j.at(i).template get(); - } + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); } -template < - typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < - is_compatible_array_type::value and - not std::is_same::value and - std::is_constructible < - BasicJsonType, typename CompatibleArrayType::value_type >::value, - int > = 0 > -void from_json(const BasicJsonType& j, CompatibleArrayType& arr) +template ::value and + not is_compatible_object_type::value and + not is_compatible_string_type::value and + not is_basic_json::value, + int > = 0 > + +auto from_json(const BasicJsonType& j, CompatibleArrayType& arr) +-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), +j.template get(), +void()) { if (JSON_UNLIKELY(not j.is_array())) { @@ -224,7 +227,7 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr) std::string(j.type_name()))); } - from_json_array_impl(j, arr, priority_tag<2> {}); + from_json_array_impl(j, arr, priority_tag<3> {}); } template::value and not is_compatible_object_type< - BasicJsonType, CompatibleArrayType>::value, + BasicJsonType, CompatibleArrayType>::value and + not is_compatible_string_type::value, int> = 0> void to_json(BasicJsonType& j, const CompatibleArrayType& arr) { diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 39ef6f75..0383472b 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -127,9 +127,6 @@ struct is_compatible_array_type_impl < is_detected::value >> { static constexpr auto value = not( - is_compatible_object_type::value or - std::is_constructible::value or is_basic_json_nested_type::value); }; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 4590b694..a90b52ae 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -487,9 +487,6 @@ struct is_compatible_array_type_impl < is_detected::value >> { static constexpr auto value = not( - is_compatible_object_type::value or - std::is_constructible::value or is_basic_json_nested_type::value); }; @@ -1124,16 +1121,6 @@ void from_json(const BasicJsonType& j, EnumType& e) e = static_cast(val); } -template -void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& 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()))); - } - arr = *j.template get_ptr(); -} - // forward_list doesn't have an insert method template::value, int> = 0> @@ -1163,24 +1150,28 @@ void from_json(const BasicJsonType& j, std::valarray& l) std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l)); } -template -void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/) +template +void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) { - using std::end; + arr = *j.template get_ptr(); +} - std::transform(j.begin(), j.end(), - std::inserter(arr, end(arr)), [](const BasicJsonType & i) +template +auto from_json_array_impl(const BasicJsonType& j, std::array& arr, + priority_tag<2> /*unused*/) +-> decltype(j.template get(), void()) +{ + for (std::size_t i = 0; i < N; ++i) { - // get() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get(); - }); + arr[i] = j.at(i).template get(); + } } template auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/) -> decltype( arr.reserve(std::declval()), + j.template get(), void()) { using std::end; @@ -1195,25 +1186,34 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio }); } -template -void from_json_array_impl(const BasicJsonType& j, std::array& arr, priority_tag<2> /*unused*/) +template +void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, + priority_tag<0> /*unused*/) { - for (std::size_t i = 0; i < N; ++i) + using std::end; + + std::transform( + j.begin(), j.end(), std::inserter(arr, end(arr)), + [](const BasicJsonType & i) { - arr[i] = j.at(i).template get(); - } + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); } -template < - typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < - is_compatible_array_type::value and - not std::is_same::value and - std::is_constructible < - BasicJsonType, typename CompatibleArrayType::value_type >::value, - int > = 0 > -void from_json(const BasicJsonType& j, CompatibleArrayType& arr) +template ::value and + not is_compatible_object_type::value and + not is_compatible_string_type::value and + not is_basic_json::value, + int > = 0 > + +auto from_json(const BasicJsonType& j, CompatibleArrayType& arr) +-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), +j.template get(), +void()) { if (JSON_UNLIKELY(not j.is_array())) { @@ -1221,7 +1221,7 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr) std::string(j.type_name()))); } - from_json_array_impl(j, arr, priority_tag<2> {}); + from_json_array_impl(j, arr, priority_tag<3> {}); } template::value and not is_compatible_object_type< - BasicJsonType, CompatibleArrayType>::value, + BasicJsonType, CompatibleArrayType>::value and + not is_compatible_string_type::value, int> = 0> void to_json(BasicJsonType& j, const CompatibleArrayType& arr) {