Skip to content

Commit 96c1b52

Browse files
authored
Fix conversion to std::optional (#4742)
* ⚗️ remove JSON_USE_IMPLICIT_CONVERSIONS check for from_json(json, std::optional) Signed-off-by: Niels Lohmann <[email protected]> * ⚗️ remove JSON_USE_IMPLICIT_CONVERSIONS check for from_json(json, std::optional) Signed-off-by: Niels Lohmann <[email protected]> * ⚗️ remove JSON_USE_IMPLICIT_CONVERSIONS check for from_json(json, std::optional) Signed-off-by: Niels Lohmann <[email protected]> * ⚗️ remove JSON_USE_IMPLICIT_CONVERSIONS check for from_json(json, std::optional) Signed-off-by: Niels Lohmann <[email protected]> * ⚗️ remove JSON_USE_IMPLICIT_CONVERSIONS check for from_json(json, std::optional) Signed-off-by: Niels Lohmann <[email protected]> * ⚗️ add C++ standard library as matrix option Signed-off-by: Niels Lohmann <[email protected]> * ⏪ remove inline Signed-off-by: Niels Lohmann <[email protected]> --------- Signed-off-by: Niels Lohmann <[email protected]>
1 parent 4cca3b9 commit 96c1b52

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

Diff for: include/nlohmann/detail/conversions/from_json.hpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
#include <forward_list> // forward_list
1414
#include <iterator> // inserter, front_inserter, end
1515
#include <map> // map
16-
#ifdef JSON_HAS_CPP_17
17-
#include <optional> // optional
18-
#endif
1916
#include <string> // string
2017
#include <tuple> // tuple, make_tuple
2118
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
@@ -32,6 +29,11 @@
3229
#include <nlohmann/detail/string_concat.hpp>
3330
#include <nlohmann/detail/value_t.hpp>
3431

32+
// include after macro_scope.hpp
33+
#ifdef JSON_HAS_CPP_17
34+
#include <optional> // optional
35+
#endif
36+
3537
NLOHMANN_JSON_NAMESPACE_BEGIN
3638
namespace detail
3739
{
@@ -47,7 +49,6 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4749
}
4850

4951
#ifdef JSON_HAS_CPP_17
50-
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
5152
template<typename BasicJsonType, typename T>
5253
void from_json(const BasicJsonType& j, std::optional<T>& opt)
5354
{
@@ -60,8 +61,6 @@ void from_json(const BasicJsonType& j, std::optional<T>& opt)
6061
opt.emplace(j.template get<T>());
6162
}
6263
}
63-
64-
#endif // JSON_USE_IMPLICIT_CONVERSIONS
6564
#endif // JSON_HAS_CPP_17
6665

6766
// overloads for basic_json template parameters

Diff for: include/nlohmann/detail/conversions/to_json.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ struct external_constructor<value_t::object>
267267
#ifdef JSON_HAS_CPP_17
268268
template<typename BasicJsonType, typename T,
269269
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
270-
void to_json(BasicJsonType& j, const std::optional<T>& opt)
270+
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
271271
{
272272
if (opt.has_value())
273273
{

Diff for: single_include/nlohmann/json.hpp

+6-7
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,6 @@
173173
#include <forward_list> // forward_list
174174
#include <iterator> // inserter, front_inserter, end
175175
#include <map> // map
176-
#ifdef JSON_HAS_CPP_17
177-
#include <optional> // optional
178-
#endif
179176
#include <string> // string
180177
#include <tuple> // tuple, make_tuple
181178
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
@@ -4817,6 +4814,11 @@ NLOHMANN_JSON_NAMESPACE_END
48174814
// #include <nlohmann/detail/value_t.hpp>
48184815

48194816

4817+
// include after macro_scope.hpp
4818+
#ifdef JSON_HAS_CPP_17
4819+
#include <optional> // optional
4820+
#endif
4821+
48204822
NLOHMANN_JSON_NAMESPACE_BEGIN
48214823
namespace detail
48224824
{
@@ -4832,7 +4834,6 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
48324834
}
48334835

48344836
#ifdef JSON_HAS_CPP_17
4835-
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
48364837
template<typename BasicJsonType, typename T>
48374838
void from_json(const BasicJsonType& j, std::optional<T>& opt)
48384839
{
@@ -4845,8 +4846,6 @@ void from_json(const BasicJsonType& j, std::optional<T>& opt)
48454846
opt.emplace(j.template get<T>());
48464847
}
48474848
}
4848-
4849-
#endif // JSON_USE_IMPLICIT_CONVERSIONS
48504849
#endif // JSON_HAS_CPP_17
48514850

48524851
// overloads for basic_json template parameters
@@ -5914,7 +5913,7 @@ struct external_constructor<value_t::object>
59145913
#ifdef JSON_HAS_CPP_17
59155914
template<typename BasicJsonType, typename T,
59165915
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
5917-
void to_json(BasicJsonType& j, const std::optional<T>& opt)
5916+
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
59185917
{
59195918
if (opt.has_value())
59205919
{

Diff for: tests/src/unit-regression2.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ using ordered_json = nlohmann::ordered_json;
3636
#include <variant>
3737
#endif
3838

39+
#ifdef JSON_HAS_CPP_17
40+
#if __has_include(<optional>)
41+
#include <optional>
42+
#elif __has_include(<experimental/optional>)
43+
#include <experimental/optional>
44+
#endif
45+
#endif
46+
3947
#ifdef JSON_HAS_CPP_20
4048
#if __has_include(<span>)
4149
#include <span>
@@ -390,6 +398,19 @@ struct Example_3810
390398

391399
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example_3810, bla); // NOLINT(misc-use-internal-linkage)
392400

401+
/////////////////////////////////////////////////////////////////////
402+
// for #4740
403+
/////////////////////////////////////////////////////////////////////
404+
405+
#ifdef JSON_HAS_CPP_17
406+
struct Example_4740
407+
{
408+
std::optional<std::string> host = std::nullopt;
409+
std::optional<int> port = std::nullopt;
410+
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Example_4740, host, port)
411+
};
412+
#endif
413+
393414
TEST_CASE("regression tests 2")
394415
{
395416
SECTION("issue #1001 - Fix memory leak during parser callback")
@@ -1037,6 +1058,28 @@ TEST_CASE("regression tests 2")
10371058
oj["test"] = states;
10381059
CHECK(oj["test"].dump() == expected);
10391060
}
1061+
1062+
#ifdef JSON_HAS_CPP_17
1063+
SECTION("issue #4740 - build issue with std::optional")
1064+
{
1065+
const auto t1 = Example_4740();
1066+
const auto j1 = nlohmann::json(t1);
1067+
CHECK(j1.dump() == "{\"host\":null,\"port\":null}");
1068+
const auto t2 = j1.get<Example_4740>();
1069+
CHECK(!t2.host.has_value());
1070+
CHECK(!t2.port.has_value());
1071+
1072+
// improve coverage
1073+
auto t3 = Example_4740();
1074+
t3.port = 80;
1075+
t3.host = "example.com";
1076+
const auto j2 = nlohmann::json(t3);
1077+
CHECK(j2.dump() == "{\"host\":\"example.com\",\"port\":80}");
1078+
const auto t4 = j2.get<Example_4740>();
1079+
CHECK(t4.host.has_value());
1080+
CHECK(t4.port.has_value());
1081+
}
1082+
#endif
10401083
}
10411084

10421085
DOCTEST_CLANG_SUPPRESS_WARNING_POP

0 commit comments

Comments
 (0)