From 2bc685f6b4ae2f53d80eaf526a073244c060a80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Wed, 9 Nov 2016 23:55:03 +0100 Subject: [PATCH] to_json and from_json takes both two arguments now the first is the basic_json type, the second the user-defined type --- src/json.hpp | 49 +++++++++++++++++++------------------------ test/src/unit-udt.cpp | 35 +++++++++++++++++-------------- 2 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index bd59e83b..4f471070 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -155,22 +155,21 @@ void from_json(); struct to_json_fn { - template + template constexpr auto - operator()(T &&val) const noexcept(noexcept(to_json(std::forward(val)))) - -> decltype(to_json(std::forward(val))) + operator()(Json&& j, T &&val) const noexcept(noexcept(to_json(std::forward(j), std::forward(val)))) + -> decltype(to_json(std::forward(j), std::forward(val)), void()) { - return to_json(std::forward(val)); + return to_json(std::forward(j), std::forward(val)); } - }; struct from_json_fn { - template + template constexpr auto operator()(Json &&j, T &val) const noexcept(noexcept(from_json(std::forward(j), val))) - -> decltype(from_json(std::forward(j), val)) + -> decltype(from_json(std::forward(j), val), void()) { return from_json(std::forward(j), val); } @@ -219,28 +218,19 @@ inline namespace template struct adl_serializer { - template >::value>> - static auto from_json(Json&& j) -> uncvref_t(j), std::declval()), std::declval())> - { - uncvref_t ret; - ::nlohmann::from_json(std::forward(j), ret); - return ret; - } - - template - static auto from_json(Json&& j, T& val) -> decltype(::nlohmann::from_json(std::forward(j), val)) + template + static auto from_json(Json&& j, T& val) -> decltype(::nlohmann::from_json(std::forward(j), val), void()) { ::nlohmann::from_json(std::forward(j), val); } - template - static auto to_json(T&& val) -> decltype(::nlohmann::to_json(std::forward(val))) + template + static auto to_json(Json& j, T&& val) -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) { - return ::nlohmann::to_json(std::forward(val)); + ::nlohmann::to_json(j, std::forward(val)); } }; - /*! @brief a class to store JSON values @@ -1399,9 +1389,11 @@ class basic_json } // constructor chosen when JSONSerializer::to_json exists for type T - template >::to_json(std::declval>()))> + template >::to_json(std::declval(), std::declval>()))> explicit basic_json(T &&val) - : basic_json(JSONSerializer>::to_json(std::forward(val))) {} + { + JSONSerializer>::to_json(*this, std::forward(val)); + } /*! @brief create a string (explicit) @@ -3072,11 +3064,14 @@ class basic_json return get_impl(static_cast(nullptr)); } - template >::value, float>> - auto get() const -> remove_reference_t>::from_json(*this, std::declval()), std::declval())> + template >::from_json(std::declval(), std::declval()))> + auto get() const -> uncvref_t { - uncvref_t ret; - JSONSerializer>::from_json(*this, ret); + using type = uncvref_t; + static_assert(std::is_default_constructible::value && std::is_copy_constructible::value, + "user-defined types must be DefaultConstructible and CopyConstructible when used with get"); + type ret; + JSONSerializer::from_json(*this, ret); return ret; } diff --git a/test/src/unit-udt.cpp b/test/src/unit-udt.cpp index 77b31c6a..17494a45 100644 --- a/test/src/unit-udt.cpp +++ b/test/src/unit-udt.cpp @@ -70,32 +70,31 @@ private: // free to/from_json functions -json to_json(empty_type) +void to_json(json& j, empty_type) { - return json::object(); + j = json::object(); } -json to_json(pod_type const& p) +void to_json(json& j, pod_type const& p) { - return {{"a", p.a}, {"b", p.b}, {"c", p.c}}; + j = json{{"a", p.a}, {"b", p.b}, {"c", p.c}}; } -json to_json(bit_more_complex_type const& p) +void to_json(json& j, bit_more_complex_type const& p) { - using nlohmann::to_json; - return json{{"a", to_json(p.a)}, {"b", to_json(p.b)}, {"c", p.c}}; + j = json{{"a", json(p.a)}, {"b", json(p.b)}, {"c", p.c}}; } template -json to_json(optional_type const& opt) +void to_json(json& j, optional_type const& opt) { - using nlohmann::to_json; if (!opt) - return nullptr; - return json(*opt); + j = nullptr; + else + j = json(*opt); } -void from_json(json const&j, empty_type& t) +void from_json(json const& j, empty_type& t) { assert(j.empty()); t = empty_type{}; @@ -292,7 +291,8 @@ TEST_CASE("to_json free function", "[udt]") auto const e = udt::pod_type{42, 42, 42}; auto const expected = json{{"a", 42}, {"b", 42}, {"c", 42}}; - auto const j = nlohmann::to_json(e); + json j; + nlohmann::to_json(j, e); CHECK(j == expected); } @@ -303,7 +303,8 @@ TEST_CASE("to_json free function", "[udt]") auto const expected = json{{"a", {{"a", 42}, {"b", 42}, {"c", 42}}}, {"b", {{"a", 41}, {"b", 41}, {"c", 41}}}, {"c", "forty"}}; - auto const j = nlohmann::to_json(e); + json j; + nlohmann::to_json(j, e); CHECK(j == expected); } @@ -314,7 +315,8 @@ TEST_CASE("to_json free function", "[udt]") udt::optional_type o; json expected; - auto const j = nlohmann::to_json(o); + json j; + nlohmann::to_json(j, o); CHECK(expected == j); } @@ -323,7 +325,8 @@ TEST_CASE("to_json free function", "[udt]") udt::optional_type o{{42, 42, 42}}; auto const expected = json{{"a", 42}, {"b", 42}, {"c", 42}}; - auto const j = nlohmann::to_json(o); + json j; + nlohmann::to_json(j, o); CHECK(expected == j); } }