From f8e078eccfedc54cd582dc1698804a287175b083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Delrieu?= Date: Wed, 13 Oct 2021 09:43:20 +0200 Subject: [PATCH] meta: rework is_compatible/is_constructible_string_type These type traits performed an incorrect and insufficient check. Converting to a std::filesystem::path used to work by accident thanks to these brittle constraints, but the clean-up performed in #3020 broke them. --- .../nlohmann/detail/conversions/from_json.hpp | 2 +- .../nlohmann/detail/conversions/to_json.hpp | 1 + include/nlohmann/detail/meta/type_traits.hpp | 39 +++++------------ single_include/nlohmann/json.hpp | 43 ++++++------------- 4 files changed, 27 insertions(+), 58 deletions(-) diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index c7bd018e34..b7a71c48c8 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -169,7 +169,7 @@ void from_json(const BasicJsonType& j, std::valarray& l) } template -auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) -> decltype(j.template get(), void()) { for (std::size_t i = 0; i < N; ++i) diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index 06323a2729..2d48d6976a 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -9,6 +9,7 @@ #include // valarray #include // vector +#include #include #include #include diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index ca6051e7cd..984ca19319 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -309,44 +309,21 @@ struct is_constructible_object_type : is_constructible_object_type_impl {}; -template -struct is_compatible_string_type_impl : std::false_type {}; - template -struct is_compatible_string_type_impl < - BasicJsonType, CompatibleStringType, - enable_if_t::value >> +struct is_compatible_string_type { static constexpr auto value = is_constructible::value; }; template -struct is_compatible_string_type - : is_compatible_string_type_impl {}; - -template -struct is_constructible_string_type_impl : std::false_type {}; - -template -struct is_constructible_string_type_impl < - BasicJsonType, ConstructibleStringType, - enable_if_t::value >> +struct is_constructible_string_type { static constexpr auto value = is_constructible::value; }; -template -struct is_constructible_string_type - : is_constructible_string_type_impl {}; - template struct is_compatible_array_type_impl : std::false_type {}; @@ -355,7 +332,10 @@ struct is_compatible_array_type_impl < BasicJsonType, CompatibleArrayType, enable_if_t < is_detected::value&& - is_iterator_traits>>::value >> + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> { static constexpr bool value = is_constructible::value&& is_iterator_traits>>::value&& is_detected::value&& -is_complete_type < -detected_t>::value >> +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& + is_complete_type < + detected_t>::value >> { using value_type = range_value_t; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 25c6983b04..7b4a63a101 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3783,44 +3783,21 @@ struct is_constructible_object_type : is_constructible_object_type_impl {}; -template -struct is_compatible_string_type_impl : std::false_type {}; - template -struct is_compatible_string_type_impl < - BasicJsonType, CompatibleStringType, - enable_if_t::value >> +struct is_compatible_string_type { static constexpr auto value = is_constructible::value; }; template -struct is_compatible_string_type - : is_compatible_string_type_impl {}; - -template -struct is_constructible_string_type_impl : std::false_type {}; - -template -struct is_constructible_string_type_impl < - BasicJsonType, ConstructibleStringType, - enable_if_t::value >> +struct is_constructible_string_type { static constexpr auto value = is_constructible::value; }; -template -struct is_constructible_string_type - : is_constructible_string_type_impl {}; - template struct is_compatible_array_type_impl : std::false_type {}; @@ -3829,7 +3806,10 @@ struct is_compatible_array_type_impl < BasicJsonType, CompatibleArrayType, enable_if_t < is_detected::value&& - is_iterator_traits>>::value >> + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> { static constexpr bool value = is_constructible::value&& is_iterator_traits>>::value&& is_detected::value&& -is_complete_type < -detected_t>::value >> +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& + is_complete_type < + detected_t>::value >> { using value_type = range_value_t; @@ -4117,7 +4100,7 @@ void from_json(const BasicJsonType& j, std::valarray& l) } template -auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) -> decltype(j.template get(), void()) { for (std::size_t i = 0; i < N; ++i) @@ -4425,6 +4408,8 @@ constexpr const auto& from_json = detail::static_const::va #include // valarray #include // vector +// #include + // #include