diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index d647d7423..797f714df 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -13,9 +13,6 @@ #include // forward_list #include // inserter, front_inserter, end #include // map -#ifdef JSON_HAS_CPP_17 - #include // optional -#endif #include // string #include // tuple, make_tuple #include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible @@ -32,6 +29,11 @@ #include #include +// include after macro_scope.hpp +#ifdef JSON_HAS_CPP_17 + #include // optional +#endif + NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { @@ -47,7 +49,6 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n) } #ifdef JSON_HAS_CPP_17 -#ifndef JSON_USE_IMPLICIT_CONVERSIONS template void from_json(const BasicJsonType& j, std::optional& opt) { @@ -60,8 +61,6 @@ void from_json(const BasicJsonType& j, std::optional& opt) opt.emplace(j.template get()); } } - -#endif // JSON_USE_IMPLICIT_CONVERSIONS #endif // JSON_HAS_CPP_17 // overloads for basic_json template parameters diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index ead45665f..f8413850d 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -267,7 +267,7 @@ struct external_constructor #ifdef JSON_HAS_CPP_17 template::value, int> = 0> -void to_json(BasicJsonType& j, const std::optional& opt) +void to_json(BasicJsonType& j, const std::optional& opt) noexcept { if (opt.has_value()) { diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 7d0ffaab1..f4e63aabe 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -173,9 +173,6 @@ #include // forward_list #include // inserter, front_inserter, end #include // map -#ifdef JSON_HAS_CPP_17 - #include // optional -#endif #include // string #include // tuple, make_tuple #include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible @@ -4817,6 +4814,11 @@ NLOHMANN_JSON_NAMESPACE_END // #include +// include after macro_scope.hpp +#ifdef JSON_HAS_CPP_17 + #include // optional +#endif + NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { @@ -4832,7 +4834,6 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n) } #ifdef JSON_HAS_CPP_17 -#ifndef JSON_USE_IMPLICIT_CONVERSIONS template void from_json(const BasicJsonType& j, std::optional& opt) { @@ -4845,8 +4846,6 @@ void from_json(const BasicJsonType& j, std::optional& opt) opt.emplace(j.template get()); } } - -#endif // JSON_USE_IMPLICIT_CONVERSIONS #endif // JSON_HAS_CPP_17 // overloads for basic_json template parameters @@ -5914,7 +5913,7 @@ struct external_constructor #ifdef JSON_HAS_CPP_17 template::value, int> = 0> -void to_json(BasicJsonType& j, const std::optional& opt) +void to_json(BasicJsonType& j, const std::optional& opt) noexcept { if (opt.has_value()) { diff --git a/tests/src/unit-regression2.cpp b/tests/src/unit-regression2.cpp index 2c3977fef..22bb8efc6 100644 --- a/tests/src/unit-regression2.cpp +++ b/tests/src/unit-regression2.cpp @@ -36,6 +36,14 @@ using ordered_json = nlohmann::ordered_json; #include #endif +#ifdef JSON_HAS_CPP_17 + #if __has_include() + #include + #elif __has_include() + #include + #endif +#endif + #ifdef JSON_HAS_CPP_20 #if __has_include() #include @@ -390,6 +398,19 @@ struct Example_3810 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example_3810, bla); // NOLINT(misc-use-internal-linkage) +///////////////////////////////////////////////////////////////////// +// for #4740 +///////////////////////////////////////////////////////////////////// + +#ifdef JSON_HAS_CPP_17 +struct Example_4740 +{ + std::optional host = std::nullopt; + std::optional port = std::nullopt; + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Example_4740, host, port) +}; +#endif + TEST_CASE("regression tests 2") { SECTION("issue #1001 - Fix memory leak during parser callback") @@ -1037,6 +1058,28 @@ TEST_CASE("regression tests 2") oj["test"] = states; CHECK(oj["test"].dump() == expected); } + +#ifdef JSON_HAS_CPP_17 + SECTION("issue #4740 - build issue with std::optional") + { + const auto t1 = Example_4740(); + const auto j1 = nlohmann::json(t1); + CHECK(j1.dump() == "{\"host\":null,\"port\":null}"); + const auto t2 = j1.get(); + CHECK(!t2.host.has_value()); + CHECK(!t2.port.has_value()); + + // improve coverage + auto t3 = Example_4740(); + t3.port = 80; + t3.host = "example.com"; + const auto j2 = nlohmann::json(t3); + CHECK(j2.dump() == "{\"host\":\"example.com\",\"port\":80}"); + const auto t4 = j2.get(); + CHECK(t4.host.has_value()); + CHECK(t4.port.has_value()); + } +#endif } DOCTEST_CLANG_SUPPRESS_WARNING_POP