Skip to content

Commit

Permalink
Merge b61d563 into a82c80e
Browse files Browse the repository at this point in the history
  • Loading branch information
nlohmann committed May 20, 2020
2 parents a82c80e + b61d563 commit 60276e1
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ script:
# make sure CXX is correctly set
- if [[ "${COMPILER}" != "" ]]; then export CXX=${COMPILER}; fi
- if [[ "${CXXFLAGS}" != "" ]]; then export CXXFLAGS=${CXXFLAGS}; fi
# by default, use the single-header version
- if [[ "${MULTIPLE_HEADERS}" == "" ]]; then export MULTIPLE_HEADERS=OFF; fi

Expand Down
15 changes: 15 additions & 0 deletions include/nlohmann/detail/conversions/from_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,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
Expand Down
16 changes: 16 additions & 0 deletions include/nlohmann/detail/conversions/to_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,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
Expand Down
8 changes: 8 additions & 0 deletions include/nlohmann/detail/macro_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
#define JSON_HAS_CPP_14
#endif

#ifdef JSON_HAS_CPP_17
#if __has_include(<optional>)
#include <optional>
#elif __has_include(<experimental/optional>)
#include <experimental/optional>
#endif
#endif

// disable float-equal warnings on GCC/clang
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic push
Expand Down
39 changes: 39 additions & 0 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2055,6 +2055,14 @@ JSON_HEDLEY_DIAGNOSTIC_POP
#define JSON_HAS_CPP_14
#endif

#ifdef JSON_HAS_CPP_17
#if __has_include(<optional>)
#include <optional>
#elif __has_include(<experimental/optional>)
#include <experimental/optional>
#endif
#endif

// disable float-equal warnings on GCC/clang
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic push
Expand Down Expand Up @@ -3253,6 +3261,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
Expand Down Expand Up @@ -4025,6 +4048,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
Expand Down
67 changes: 67 additions & 0 deletions test/src/unit-conversions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ using nlohmann::json;
#define JSON_HAS_CPP_14
#endif

#ifdef JSON_HAS_CPP_17
#if __has_include(<optional>)
#include <optional>
#elif __has_include(<experimental/optional>)
#include <experimental/optional>
#endif
#endif

#if defined(JSON_HAS_CPP_17)
#include <string_view>
#endif
Expand Down Expand Up @@ -1692,3 +1700,62 @@ 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, 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

0 comments on commit 60276e1

Please sign in to comment.