From d6fea62a29070610562f61d5dbcb594b093925a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Tue, 18 Oct 2016 00:37:35 +0200 Subject: [PATCH] wip: add free function to_json/from_json support --- src/json.hpp | 34 ++++++++++++++ test/src/unit-constructor3.cpp | 84 +++++++++++++++++++++++++++++----- 2 files changed, 107 insertions(+), 11 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index f8085da8d..7c428002c 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -143,6 +143,24 @@ struct has_json_traits static constexpr bool value = has_destructor>::value; }; +struct to_json_fn +{ + template + constexpr auto operator()(T&& val) const -> decltype(to_json(std::forward(val))) + { + return to_json(std::forward(val)); + } +}; + +struct from_json_fn +{ + template + constexpr auto operator()(T&& val) const -> decltype(from_json(std::forward(val))) + { + return from_json(std::forward(val)); + } +}; + /*! @brief helper class to create locales with decimal point @@ -165,6 +183,22 @@ struct DecimalSeparator : std::numpunct } +// taken from ranges-v3 +template +struct __static_const +{ + static constexpr T value{}; +}; + +template +constexpr T __static_const::value; + +inline namespace +{ + constexpr auto const& to_json = __static_const::value; + constexpr auto const& from_json = __static_const::value; +} + /*! @brief a class to store JSON values diff --git a/test/src/unit-constructor3.cpp b/test/src/unit-constructor3.cpp index d119625fa..912772f3d 100644 --- a/test/src/unit-constructor3.cpp +++ b/test/src/unit-constructor3.cpp @@ -42,22 +42,12 @@ struct pod_type { short c; }; -inline bool operator==(pod_type const& lhs, pod_type const& rhs) noexcept -{ - return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c); -} - struct bit_more_complex_type { pod_type a; pod_type b; std::string c; }; -inline bool operator==(bit_more_complex_type const &lhs, - bit_more_complex_type const &rhs) noexcept { - return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c); -} - // best optional implementation ever template class optional_type @@ -73,6 +63,43 @@ private: std::shared_ptr _val; }; +// free to/from_json functions + +json to_json(empty_type) +{ + return json::object(); +} + +json to_json(pod_type const& p) +{ + return {{"a", p.a}, {"b", p.b}, {"c", p.c}}; +} + +json to_json(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}}; +} + +template +json to_json(optional_type const& opt) +{ + using nlohmann::to_json; + if (!opt) + return nullptr; + return to_json(*opt); +} + +inline bool operator==(pod_type const& lhs, pod_type const& rhs) noexcept +{ + return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c); +} + +inline bool operator==(bit_more_complex_type const &lhs, + bit_more_complex_type const &rhs) noexcept { + return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c); +} + template inline bool operator==(optional_type const& lhs, optional_type const& rhs) { @@ -163,7 +190,7 @@ TEST_CASE("constructors for user-defined types", "[udt]") { SECTION("empty type") { - udt::empty_type const e; + udt::empty_type const e{}; auto const j = json{e}; auto k = json::object(); CHECK(j == k); @@ -300,3 +327,38 @@ TEST_CASE("get<> for user-defined types", "[udt]") } } } + +TEST_CASE("to_json free function", "[udt]") +{ + SECTION("pod_type") + { + 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); + CHECK(j == expected); + } + + SECTION("bit_more_complex_type") + { + auto const e = + udt::bit_more_complex_type{{42, 42, 42}, {41, 41, 41}, "forty"}; + 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); + CHECK(j == expected); + } + + SECTION("optional_type") + { + SECTION("from null") + { + udt::optional_type o; + + json expected; + auto const j = nlohmann::to_json(o); + CHECK(expected == j); + } + } +}