Skip to content

Commit

Permalink
to_json and from_json takes both two arguments now
Browse files Browse the repository at this point in the history
the first is the basic_json type, the second the user-defined type
  • Loading branch information
theodelrieu committed Nov 9, 2016
1 parent 4fae04c commit 2530767
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 44 deletions.
51 changes: 23 additions & 28 deletions src/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,24 +140,23 @@ void from_json();

struct to_json_fn
{
template <typename T>
template <typename Json, typename T>
constexpr auto
operator()(T &&val) const noexcept(noexcept(to_json(std::forward<T>(val))))
-> decltype(to_json(std::forward<T>(val)))
operator()(Json&& j, T &&val) const noexcept(noexcept(to_json(std::forward<Json>(j), std::forward<T>(val))))
-> decltype(to_json(std::forward<Json>(j), std::forward<T>(val)), void())
{
return to_json(std::forward<T>(val));
to_json(std::forward<Json>(j), std::forward<T>(val));
}

};

struct from_json_fn
{
template <typename T, typename Json>
template <typename Json, typename T>
constexpr auto operator()(Json &&j, T &val) const
noexcept(noexcept(from_json(std::forward<Json>(j), val)))
-> decltype(from_json(std::forward<Json>(j), val))
-> decltype(from_json(std::forward<Json>(j), val), void())
{
return from_json(std::forward<Json>(j), val);
from_json(std::forward<Json>(j), val);
}
};

Expand Down Expand Up @@ -205,28 +204,19 @@ inline namespace
template <typename = void, typename = void>
struct adl_serializer
{
template <typename T, typename Json, typename = enable_if_t<std::is_default_constructible<uncvref_t<T>>::value>>
static auto from_json(Json&& j) -> uncvref_t<decltype(::nlohmann::from_json(std::forward<Json>(j), std::declval<T&>()), std::declval<T>())>
{
uncvref_t<T> ret;
::nlohmann::from_json(std::forward<Json>(j), ret);
return ret;
}

template <typename T, typename Json>
static auto from_json(Json&& j, T& val) -> decltype(::nlohmann::from_json(std::forward<Json>(j), val))
template <typename Json, typename T>
static auto from_json(Json&& j, T& val) -> decltype(::nlohmann::from_json(std::forward<Json>(j), val), void())
{
::nlohmann::from_json(std::forward<Json>(j), val);
}

template <typename T>
static auto to_json(T&& val) -> decltype(::nlohmann::to_json(std::forward<T>(val)))
template <typename Json, typename T>
static auto to_json(Json& j, T&& val) -> decltype(::nlohmann::to_json(j, std::forward<T>(val)), void())
{
return ::nlohmann::to_json(std::forward<T>(val));
::nlohmann::to_json(j, std::forward<T>(val));
}
};


/*!
@brief a class to store JSON values
Expand Down Expand Up @@ -1310,9 +1300,11 @@ class basic_json
}

// constructor chosen when JSONSerializer::to_json exists for type T
template <typename T, typename = decltype(JSONSerializer<uncvref_t<T>>::to_json(std::declval<uncvref_t<T>>()))>
template <typename T, typename = decltype(JSONSerializer<uncvref_t<T>>::to_json(std::declval<basic_json&>(), std::declval<uncvref_t<T>>()))>
explicit basic_json(T &&val)
: basic_json(JSONSerializer<uncvref_t<T>>::to_json(std::forward<T>(val))) {}
{
JSONSerializer<uncvref_t<T>>::to_json(*this, std::forward<T>(val));
}

/*!
@brief create a string (explicit)
Expand Down Expand Up @@ -2991,11 +2983,14 @@ class basic_json
return get_impl(static_cast<ValueType*>(nullptr));
}

template <typename ValueType, typename = enable_if_t<std::is_default_constructible<uncvref_t<ValueType>>::value, float>>
auto get() const -> remove_reference_t<decltype(JSONSerializer<uncvref_t<ValueType>>::from_json(*this, std::declval<ValueType&>()), std::declval<ValueType>())>
template <typename ValueType, typename = decltype(JSONSerializer<uncvref_t<ValueType>>::from_json(std::declval<basic_json>(), std::declval<ValueType&>()))>
auto get() const -> uncvref_t<ValueType>
{
uncvref_t<ValueType> ret;
JSONSerializer<uncvref_t<ValueType>>::from_json(*this, ret);
using type = uncvref_t<ValueType>;
static_assert(std::is_default_constructible<type>::value && std::is_copy_constructible<type>::value,
"user-defined types must be DefaultConstructible and CopyConstructible when used with get");
type ret;
JSONSerializer<type>::from_json(*this, ret);
return ret;
}

Expand Down
35 changes: 19 additions & 16 deletions test/src/unit-udt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,32 +70,31 @@ class optional_type

// free to/from_json functions

json to_json(empty_type)
void to_json(json& j, empty_type)
{
return json::object();
j = json::object();
}

json to_json(pod_type const& p)
void to_json(json& j, pod_type const& p)
{
return {{"a", p.a}, {"b", p.b}, {"c", p.c}};
j = json{{"a", p.a}, {"b", p.b}, {"c", p.c}};
}

json to_json(bit_more_complex_type const& p)
void to_json(json& j, bit_more_complex_type const& p)
{
using nlohmann::to_json;
return json{{"a", to_json(p.a)}, {"b", to_json(p.b)}, {"c", p.c}};
j = json{{"a", json(p.a)}, {"b", json(p.b)}, {"c", p.c}};
}

template <typename T>
json to_json(optional_type<T> const& opt)
void to_json(json& j, optional_type<T> const& opt)
{
using nlohmann::to_json;
if (!opt)
return nullptr;
return json(*opt);
j = nullptr;
else
j = json(*opt);
}

void from_json(json const&j, empty_type& t)
void from_json(json const& j, empty_type& t)
{
assert(j.empty());
t = empty_type{};
Expand Down Expand Up @@ -292,7 +291,8 @@ TEST_CASE("to_json free function", "[udt]")
auto const e = udt::pod_type{42, 42, 42};
auto const expected = json{{"a", 42}, {"b", 42}, {"c", 42}};

auto const j = nlohmann::to_json(e);
json j;
nlohmann::to_json(j, e);
CHECK(j == expected);
}

Expand All @@ -303,7 +303,8 @@ TEST_CASE("to_json free function", "[udt]")
auto const expected = json{{"a", {{"a", 42}, {"b", 42}, {"c", 42}}},
{"b", {{"a", 41}, {"b", 41}, {"c", 41}}},
{"c", "forty"}};
auto const j = nlohmann::to_json(e);
json j;
nlohmann::to_json(j, e);
CHECK(j == expected);
}

Expand All @@ -314,7 +315,8 @@ TEST_CASE("to_json free function", "[udt]")
udt::optional_type<udt::pod_type> o;

json expected;
auto const j = nlohmann::to_json(o);
json j;
nlohmann::to_json(j, o);
CHECK(expected == j);
}

Expand All @@ -323,7 +325,8 @@ TEST_CASE("to_json free function", "[udt]")
udt::optional_type<udt::pod_type> o{{42, 42, 42}};

auto const expected = json{{"a", 42}, {"b", 42}, {"c", 42}};
auto const j = nlohmann::to_json(o);
json j;
nlohmann::to_json(j, o);
CHECK(expected == j);
}
}
Expand Down

0 comments on commit 2530767

Please sign in to comment.