From f7971f04a5e21dcaaa0d559abf5b4d67d854c00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Thu, 6 Sep 2018 16:08:01 +0200 Subject: [PATCH] make to_json SFINAE-correct --- include/nlohmann/adl_serializer.hpp | 6 ++- .../nlohmann/detail/conversions/to_json.hpp | 34 ++++------------ single_include/nlohmann/json.hpp | 40 +++++-------------- 3 files changed, 22 insertions(+), 58 deletions(-) diff --git a/include/nlohmann/adl_serializer.hpp b/include/nlohmann/adl_serializer.hpp index 53c9009f..58d26ea9 100644 --- a/include/nlohmann/adl_serializer.hpp +++ b/include/nlohmann/adl_serializer.hpp @@ -35,9 +35,11 @@ struct adl_serializer @param[in,out] j JSON value to write to @param[in] val value to read from */ - template - static void to_json(BasicJsonType& j, ValueType&& val) noexcept( + template + static auto to_json(BasicJsonType& j, ValueType&& val) noexcept( noexcept(::nlohmann::to_json(j, std::forward(val)))) + -> decltype(::nlohmann::to_json(j, std::forward(val)), + void()) { ::nlohmann::to_json(j, std::forward(val)); } diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index 5e631a38..8f2bd266 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -286,9 +286,12 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) external_constructor::construct(j, std::move(obj)); } -template::value, int> = 0> -void to_json(BasicJsonType& j, T (&arr)[N]) +template < + typename BasicJsonType, typename T, std::size_t N, + enable_if_t::value, + int> = 0 > +void to_json(BasicJsonType& j, const T (&arr)[N]) { external_constructor::construct(j, arr); } @@ -321,35 +324,12 @@ void to_json(BasicJsonType& j, const std::tuple& t) struct to_json_fn { - private: template - auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward(val)))) + auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward(val)))) -> decltype(to_json(j, std::forward(val)), void()) { return to_json(j, std::forward(val)); } - - template - void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept - { - static_assert(sizeof(BasicJsonType) == 0, - "could not find to_json() method in T's namespace"); - -#ifdef _MSC_VER - // MSVC does not show a stacktrace for the above assert - using decayed = uncvref_t; - static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0, - "forcing MSVC stacktrace to show which T we're talking about."); -#endif - } - - public: - template - void operator()(BasicJsonType& j, T&& val) const - noexcept(noexcept(std::declval().call(j, std::forward(val), priority_tag<1> {}))) - { - return call(j, std::forward(val), priority_tag<1> {}); - } }; } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a90b52ae..16106c2f 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -1807,9 +1807,12 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) external_constructor::construct(j, std::move(obj)); } -template::value, int> = 0> -void to_json(BasicJsonType& j, T (&arr)[N]) +template < + typename BasicJsonType, typename T, std::size_t N, + enable_if_t::value, + int> = 0 > +void to_json(BasicJsonType& j, const T (&arr)[N]) { external_constructor::construct(j, arr); } @@ -1842,35 +1845,12 @@ void to_json(BasicJsonType& j, const std::tuple& t) struct to_json_fn { - private: template - auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward(val)))) + auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward(val)))) -> decltype(to_json(j, std::forward(val)), void()) { return to_json(j, std::forward(val)); } - - template - void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept - { - static_assert(sizeof(BasicJsonType) == 0, - "could not find to_json() method in T's namespace"); - -#ifdef _MSC_VER - // MSVC does not show a stacktrace for the above assert - using decayed = uncvref_t; - static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0, - "forcing MSVC stacktrace to show which T we're talking about."); -#endif - } - - public: - template - void operator()(BasicJsonType& j, T&& val) const - noexcept(noexcept(std::declval().call(j, std::forward(val), priority_tag<1> {}))) - { - return call(j, std::forward(val), priority_tag<1> {}); - } }; } @@ -11147,9 +11127,11 @@ struct adl_serializer @param[in,out] j JSON value to write to @param[in] val value to read from */ - template - static void to_json(BasicJsonType& j, ValueType&& val) noexcept( + template + static auto to_json(BasicJsonType& j, ValueType&& val) noexcept( noexcept(::nlohmann::to_json(j, std::forward(val)))) + -> decltype(::nlohmann::to_json(j, std::forward(val)), + void()) { ::nlohmann::to_json(j, std::forward(val)); }