Merge branch 'develop' of https://github.com/nlohmann/json into feature/optional
diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp
index 438b84a..3300b49 100644
--- a/include/nlohmann/detail/conversions/from_json.hpp
+++ b/include/nlohmann/detail/conversions/from_json.hpp
@@ -32,6 +32,21 @@
n = nullptr;
}
+#ifdef JSON_HAS_CPP_17
+template<typename BasicJsonType, typename T>
+void from_json(const BasicJsonType& j, std::optional<T>& opt)
+{
+ if (j.is_null())
+ {
+ opt = std::nullopt;
+ }
+ else
+ {
+ opt = j.template get<T>();
+ }
+}
+#endif
+
// overloads for basic_json template parameters
template < typename BasicJsonType, typename ArithmeticType,
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp
index b45004f..dcee1fd 100644
--- a/include/nlohmann/detail/conversions/to_json.hpp
+++ b/include/nlohmann/detail/conversions/to_json.hpp
@@ -219,6 +219,22 @@
// to_json //
/////////////
+#ifdef JSON_HAS_CPP_17
+template<typename BasicJsonType, typename T,
+ enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
+void to_json(BasicJsonType& j, const std::optional<T>& opt)
+{
+ if (opt.has_value())
+ {
+ j = *opt;
+ }
+ else
+ {
+ j = nullptr;
+ }
+}
+#endif
+
template<typename BasicJsonType, typename T,
enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
void to_json(BasicJsonType& j, T b) noexcept
diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp
index 77acf04..412858e 100644
--- a/include/nlohmann/detail/macro_scope.hpp
+++ b/include/nlohmann/detail/macro_scope.hpp
@@ -31,6 +31,10 @@
#define JSON_HAS_CPP_14
#endif
+#ifdef JSON_HAS_CPP_17
+ #include <optional>
+#endif
+
// disable float-equal warnings on GCC/clang
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic push
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index 8b6344f..897d6b6 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -2108,6 +2108,10 @@
#define JSON_HAS_CPP_14
#endif
+#ifdef JSON_HAS_CPP_17
+ #include <optional>
+#endif
+
// disable float-equal warnings on GCC/clang
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic push
@@ -3518,6 +3522,21 @@
n = nullptr;
}
+#ifdef JSON_HAS_CPP_17
+template<typename BasicJsonType, typename T>
+void from_json(const BasicJsonType& j, std::optional<T>& opt)
+{
+ if (j.is_null())
+ {
+ opt = std::nullopt;
+ }
+ else
+ {
+ opt = j.template get<T>();
+ }
+}
+#endif
+
// overloads for basic_json template parameters
template < typename BasicJsonType, typename ArithmeticType,
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
@@ -4294,6 +4313,22 @@
// to_json //
/////////////
+#ifdef JSON_HAS_CPP_17
+template<typename BasicJsonType, typename T,
+ enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
+void to_json(BasicJsonType& j, const std::optional<T>& opt)
+{
+ if (opt.has_value())
+ {
+ j = *opt;
+ }
+ else
+ {
+ j = nullptr;
+ }
+}
+#endif
+
template<typename BasicJsonType, typename T,
enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::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 7f59c63..6de003d 100644
--- a/test/src/unit-conversions.cpp
+++ b/test/src/unit-conversions.cpp
@@ -1704,6 +1704,65 @@
}
#ifdef JSON_HAS_CPP_17
+TEST_CASE("std::optional")
+{
+ SECTION("null")
+ {
+ json j_null;
+ std::optional<std::string> opt_null;
+
+ CHECK(json(opt_null) == j_null);
+ CHECK(std::optional<std::string>(j_null) == std::nullopt);
+ }
+
+ SECTION("string")
+ {
+ json j_string = "string";
+ std::optional<std::string> opt_string = "string";
+
+ CHECK(json(opt_string) == j_string);
+ CHECK(std::optional<std::string>(j_string) == opt_string);
+ }
+
+ SECTION("bool")
+ {
+ json j_bool = true;
+ std::optional<bool> opt_bool = true;
+
+ CHECK(json(opt_bool) == j_bool);
+ CHECK(std::optional<bool>(j_bool) == opt_bool);
+ }
+
+ SECTION("number")
+ {
+ json j_number = 1;
+ std::optional<int> opt_int = 1;
+
+ CHECK(json(opt_int) == j_number);
+ CHECK(std::optional<int>(j_number) == opt_int);
+ }
+
+ SECTION("array")
+ {
+ json j_array = {1, 2, nullptr};
+ std::vector<std::optional<int>> opt_array = {{1, 2, std::nullopt}};
+
+ CHECK(json(opt_array) == j_array);
+ CHECK(std::vector<std::optional<int>>(j_array) == opt_array);
+ }
+
+ SECTION("object")
+ {
+ json j_object = {{"one", 1}, {"two", 2}, {"zero", nullptr}};
+ std::map<std::string, std::optional<int>> opt_object {{"one", 1}, {"two", 2}, {"zero", std::nullopt}};
+
+ CHECK(json(opt_object) == j_object);
+ CHECK(std::map<std::string, std::optional<int>>(j_object) == opt_object);
+ }
+}
+#endif
+
+#ifdef JSON_HAS_CPP_17
#undef JSON_HAS_CPP_17
#endif