Added new macros NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT.

This commit is contained in:
Chaoya Li 2021-06-15 10:14:44 +08:00 committed by Paul Ketelsen
parent 4d4c273036
commit 27b4256ba8
3 changed files with 120 additions and 1 deletions

View File

@ -334,6 +334,7 @@
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, default_obj.v1);
/*!
@brief macro
@ -344,6 +345,10 @@
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
/*!
@brief macro
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
@ -353,6 +358,10 @@
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
// inspired from https://stackoverflow.com/a/26745591
// allows to call any std function as if (e.g. with begin):

View File

@ -2631,6 +2631,7 @@ using is_detected_convertible =
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, default_obj.v1);
/*!
@brief macro
@ -2641,6 +2642,10 @@ using is_detected_convertible =
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
/*!
@brief macro
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
@ -2650,6 +2655,10 @@ using is_detected_convertible =
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
// inspired from https://stackoverflow.com/a/26745591
// allows to call any std function as if (e.g. with begin):

View File

@ -59,6 +59,42 @@ class person_with_private_data
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
};
class person_with_private_data_2
{
private:
std::string name{};
int age = 0;
json metadata = nullptr;
public:
bool operator==(const person_with_private_data_2& rhs) const
{
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
}
person_with_private_data_2() = default;
person_with_private_data_2(std::string name_, int age_, json metadata_)
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
{}
std::string getName()
{
return name;
}
int getAge()
{
return age;
}
json getMetadata()
{
return metadata;
}
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person_with_private_data_2, age, name, metadata)
};
class person_without_private_data_1
{
public:
@ -103,6 +139,41 @@ class person_without_private_data_2
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)
class person_without_private_data_3
{
public:
std::string name{};
int age = 0;
json metadata = nullptr;
bool operator==(const person_without_private_data_3& rhs) const
{
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
}
person_without_private_data_3() = default;
person_without_private_data_3(std::string name_, int age_, json metadata_)
: name(std::move(name_))
, age(age_)
, metadata(std::move(metadata_))
{}
std::string getName()
{
return name;
}
int getAge()
{
return age;
}
json getMetadata()
{
return metadata;
}
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person_without_private_data_3, age, name, metadata)
class person_with_private_alphabet
{
public:
@ -231,7 +302,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f
} // namespace persons
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE", T,
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
persons::person_with_private_data,
persons::person_without_private_data_1,
persons::person_without_private_data_2)
@ -257,6 +328,36 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU
}
}
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T,
persons::person_with_private_data_2,
persons::person_without_private_data_3)
{
SECTION("person with default values")
{
// serialization
T p1("Erik", 1, {{"haircuts", 2}});
CHECK(json(p1).dump() == "{\"age\":1,\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}");
// deserialization
auto p2 = json(p1).get<T>();
CHECK(p2 == p1);
// roundtrip
CHECK(T(json(p1)) == p1);
CHECK(json(T(json(p1))) == json(p1));
// check default value in case of missing field
json j = json(p1);
j.erase("name");
j.erase("age");
j.erase("metadata");
T p3 = j.get<T>();
CHECK(p3.getName() == "");
CHECK(p3.getAge() == 0);
CHECK(p3.getMetadata() == nullptr);
}
}
TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
persons::person_with_private_alphabet,
persons::person_with_public_alphabet)