🚧 conversions for std::optional

This commit is contained in:
Niels Lohmann 2019-11-23 00:21:33 +01:00
parent c0f52edbc3
commit df30a0ea07
No known key found for this signature in database
GPG Key ID: 7F3CEA63AE251B69
4 changed files with 139 additions and 1 deletions

View File

@ -13,6 +13,10 @@
#include <utility> // pair, declval
#include <valarray> // valarray
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
@ -33,6 +37,21 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
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 and

View File

@ -10,6 +10,10 @@
#include <valarray> // valarray
#include <vector> // vector
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
@ -198,6 +202,22 @@ struct external_constructor<value_t::object>
// 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

View File

@ -69,6 +69,10 @@ SOFTWARE.
#include <utility> // pair, declval
#include <valarray> // valarray
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
// #include <nlohmann/detail/exceptions.hpp>
@ -2904,6 +2908,21 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
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 and
@ -3272,6 +3291,10 @@ constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::va
#include <valarray> // valarray
#include <vector> // vector
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
@ -3642,6 +3665,22 @@ struct external_constructor<value_t::object>
// 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

View File

@ -50,6 +50,7 @@ using nlohmann::json;
#endif
#if defined(JSON_HAS_CPP_17)
#include <optional>
#include <string_view>
#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<TaskState>());
}
}
#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, 3};
std::optional<std::vector<int>> opt_array = {{1, 2, 3}};
CHECK(json(opt_array) == j_array);
CHECK(std::optional<std::vector<int>>(j_array) == opt_array);
}
SECTION("object")
{
json j_object = {{"one", 1}, {"two", 2}};
std::map<std::string, int> m {{"one", 1}, {"two", 2}};
std::optional<std::map<std::string, int>> opt_object = m;
CHECK(json(opt_object) == j_object);
CHECK(std::optional<std::map<std::string, int>>(j_object) == opt_object);
}
}
#endif