From df30a0ea07ff9b922dc3ea49047f996446cf38c6 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sat, 23 Nov 2019 00:21:33 +0100 Subject: [PATCH] :construction: conversions for std::optional --- .../nlohmann/detail/conversions/from_json.hpp | 19 ++++++ .../nlohmann/detail/conversions/to_json.hpp | 20 ++++++ single_include/nlohmann/json.hpp | 39 ++++++++++++ test/src/unit-conversions.cpp | 62 ++++++++++++++++++- 4 files changed, 139 insertions(+), 1 deletion(-) diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index c389dca7a..34a9c327e 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -13,6 +13,10 @@ #include // pair, declval #include // valarray +#ifdef JSON_HAS_CPP_17 + #include // optional +#endif + #include #include #include @@ -33,6 +37,21 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n) n = nullptr; } +#ifdef JSON_HAS_CPP_17 +template +void from_json(const BasicJsonType& j, std::optional& opt) +{ + if (j.is_null()) + { + opt = std::nullopt; + } + else + { + opt = j.template get(); + } +} +#endif + // overloads for basic_json template parameters template::value and diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index a1def699f..040ba795f 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -10,6 +10,10 @@ #include // valarray #include // vector +#ifdef JSON_HAS_CPP_17 + #include // optional +#endif + #include #include #include @@ -198,6 +202,22 @@ struct external_constructor // to_json // ///////////// +#ifdef JSON_HAS_CPP_17 +template::value, int> = 0> +void to_json(BasicJsonType& j, const std::optional& opt) +{ + if (opt.has_value()) + { + j = *opt; + } + else + { + j = nullptr; + } +} +#endif + template::value, int> = 0> void to_json(BasicJsonType& j, T b) noexcept diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e2a68e6f5..8cfebd025 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -69,6 +69,10 @@ SOFTWARE. #include // pair, declval #include // valarray +#ifdef JSON_HAS_CPP_17 + #include // optional +#endif + // #include @@ -2904,6 +2908,21 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n) n = nullptr; } +#ifdef JSON_HAS_CPP_17 +template +void from_json(const BasicJsonType& j, std::optional& opt) +{ + if (j.is_null()) + { + opt = std::nullopt; + } + else + { + opt = j.template get(); + } +} +#endif + // overloads for basic_json template parameters template::value and @@ -3272,6 +3291,10 @@ constexpr const auto& from_json = detail::static_const::va #include // valarray #include // vector +#ifdef JSON_HAS_CPP_17 + #include // optional +#endif + // #include @@ -3642,6 +3665,22 @@ struct external_constructor // to_json // ///////////// +#ifdef JSON_HAS_CPP_17 +template::value, int> = 0> +void to_json(BasicJsonType& j, const std::optional& opt) +{ + if (opt.has_value()) + { + j = *opt; + } + else + { + j = nullptr; + } +} +#endif + template::value, int> = 0> void to_json(BasicJsonType& j, T b) noexcept diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index 8477cf639..c0c52f605 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -50,6 +50,7 @@ using nlohmann::json; #endif #if defined(JSON_HAS_CPP_17) + #include #include #endif @@ -189,7 +190,6 @@ TEST_CASE("value conversion") } } - SECTION("get an object (implicit)") { json::object_t o_reference = {{"object", json::object()}, @@ -1575,3 +1575,63 @@ TEST_CASE("JSON to enum mapping") CHECK(TS_INVALID == json("what?").get()); } } + +#ifdef JSON_HAS_CPP_17 +TEST_CASE("std::optional") +{ + SECTION("null") + { + json j_null; + std::optional opt_null; + + CHECK(json(opt_null) == j_null); + //CHECK(std::optional(j_null) == std::nullopt); + } + + SECTION("string") + { + json j_string = "string"; + std::optional opt_string = "string"; + + CHECK(json(opt_string) == j_string); + CHECK(std::optional(j_string) == opt_string); + } + + SECTION("bool") + { + json j_bool = true; + std::optional opt_bool = true; + + CHECK(json(opt_bool) == j_bool); + CHECK(std::optional(j_bool) == opt_bool); + } + + SECTION("number") + { + json j_number = 1; + std::optional opt_int = 1; + + CHECK(json(opt_int) == j_number); + CHECK(std::optional(j_number) == opt_int); + } + + SECTION("array") + { + json j_array = {1, 2, 3}; + std::optional> opt_array = {{1, 2, 3}}; + + CHECK(json(opt_array) == j_array); + CHECK(std::optional>(j_array) == opt_array); + } + + SECTION("object") + { + json j_object = {{"one", 1}, {"two", 2}}; + std::map m {{"one", 1}, {"two", 2}}; + std::optional> opt_object = m; + + CHECK(json(opt_object) == j_object); + CHECK(std::optional>(j_object) == opt_object); + } +} +#endif