Add serialization-only user defined type macros (#3816)

This commit is contained in:
Vyacheslav Zhdanovskiy 2023-11-26 15:18:20 +03:00 committed by GitHub
parent 5d931c59a3
commit 360ce457f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 293 additions and 13 deletions

View File

@ -0,0 +1,38 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;
namespace ns
{
class person
{
private:
std::string name = "John Doe";
std::string address = "123 Fake St";
int age = -1;
public:
// No default constructor
person(std::string name_, std::string address_, int age_)
: name(std::move(name_)), address(std::move(address_)), age(age_)
{}
friend void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
{
nlohmann_json_j["name"] = nlohmann_json_t.name;
nlohmann_json_j["address"] = nlohmann_json_t.address;
nlohmann_json_j["age"] = nlohmann_json_t.age;
}
};
} // namespace ns
int main()
{
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
// serialization: person -> json
json j = p;
std::cout << "serialization: " << j << std::endl;
}

View File

@ -0,0 +1 @@
serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

View File

@ -0,0 +1,33 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;
namespace ns
{
class person
{
private:
std::string name = "John Doe";
std::string address = "123 Fake St";
int age = -1;
public:
// No default constructor
person(std::string name_, std::string address_, int age_)
: name(std::move(name_)), address(std::move(address_)), age(age_)
{}
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age)
};
} // namespace ns
int main()
{
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
// serialization: person -> json
json j = p;
std::cout << "serialization: " << j << std::endl;
}

View File

@ -0,0 +1 @@
serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

View File

@ -0,0 +1,31 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;
namespace ns
{
struct person
{
std::string name;
std::string address;
int age;
};
void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
{
nlohmann_json_j["name"] = nlohmann_json_t.name;
nlohmann_json_j["address"] = nlohmann_json_t.address;
nlohmann_json_j["age"] = nlohmann_json_t.age;
}
} // namespace ns
int main()
{
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
// serialization: person -> json
json j = p;
std::cout << "serialization: " << j << std::endl;
}

View File

@ -0,0 +1 @@
serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

View File

@ -0,0 +1,26 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;
namespace ns
{
struct person
{
std::string name;
std::string address;
int age;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(person, name, address, age)
} // namespace ns
int main()
{
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
// serialization: person -> json
json j = p;
std::cout << "serialization: " << j << std::endl;
}

View File

@ -0,0 +1 @@
serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

View File

@ -50,9 +50,11 @@ header. See also the [macro overview page](../../features/macros.md).
## Serialization/deserialization macros ## Serialization/deserialization macros
- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)**<br>**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...)**][DefInt] - [**NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)**<br>**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...)**
<br>**NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, member...)**][DefInt]
\- serialization/deserialization of types _with_ access to private variables \- serialization/deserialization of types _with_ access to private variables
- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)**<br>**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...)**][DefNonInt] - [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)**<br>**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...)**
<br>**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, member...)**][DefNonInt]
\- serialization/deserialization of types _without_ access to private variables \- serialization/deserialization of types _without_ access to private variables
- [**NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)**](nlohmann_json_serialize_enum.md) - serialization/deserialization of enum types - [**NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)**](nlohmann_json_serialize_enum.md) - serialization/deserialization of enum types

View File

@ -1,8 +1,9 @@
# NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT # NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE
```cpp ```cpp
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) // (1) #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) // (1)
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3)
``` ```
These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as
@ -16,6 +17,7 @@ parameter is the name of the class/struct, and all remaining parameters name the
2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the 2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the
respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function
default constructs an object and uses its values as the defaults when calling the `value` function. default constructs an object and uses its values as the defaults when calling the `value` function.
3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization in required.
## Parameters ## Parameters
@ -31,7 +33,7 @@ The macros add two friend functions to the class which take care of the serializ
```cpp ```cpp
friend void to_json(nlohmann::json&, const type&); friend void to_json(nlohmann::json&, const type&);
friend void from_json(const nlohmann::json&, type&); friend void from_json(const nlohmann::json&, type&); // except (3)
``` ```
See examples below for the concrete generated code. See examples below for the concrete generated code.
@ -40,7 +42,7 @@ See examples below for the concrete generated code.
!!! info "Prerequisites" !!! info "Prerequisites"
1. The type `type` must be default constructible. See [How can I use `get()` for non-default 1. The type `type` must be default constructible (except (3)). See [How can I use `get()` for non-default
constructible/non-copyable types?][GetNonDefNonCopy] for how to overcome this limitation. constructible/non-copyable types?][GetNonDefNonCopy] for how to overcome this limitation.
2. The macro must be used inside the type (class/struct). 2. The macro must be used inside the type (class/struct).
@ -108,15 +110,42 @@ See examples below for the concrete generated code.
The macro is equivalent to: The macro is equivalent to:
```cpp hl_lines="21 22 23 24 25 26 27 28 29 30 31 32 33 34 35" ```cpp hl_lines="22 23 24 25 26 27 28 29 30 31 32 33 34 35"
--8<-- "examples/nlohmann_define_type_intrusive_with_default_explicit.cpp" --8<-- "examples/nlohmann_define_type_intrusive_with_default_explicit.cpp"
``` ```
Note how a default-initialized `person` object is used in the `from_json` to fill missing values. Note how a default-initialized `person` object is used in the `from_json` to fill missing values.
??? example "Example (3): NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE"
Consider the following complete example:
```cpp hl_lines="22"
--8<-- "examples/nlohmann_define_type_intrusive_only_serialize_macro.cpp"
```
Output:
```json
--8<-- "examples/nlohmann_define_type_intrusive_only_serialize_macro.output"
```
Notes:
- `ns::person` is non-default-constructible. This allows this macro to be used instead of
`NLOHMANN_DEFINE_TYPE_INTRUSIVE` and `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT`.
- `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE` applicable, but not
`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE`.
- The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE` is used _inside_ the class.
The macro is equivalent to:
```cpp hl_lines="22 22 23 24 25 26 27"
--8<-- "examples/nlohmann_define_type_intrusive_only_serialize_explicit.cpp"
```
## See also ## See also
- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_non_intrusive.md) - [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE{_WITH_DEFAULT, _ONLY_SERIALIZE}](nlohmann_define_type_non_intrusive.md)
for a similar macro that can be defined _outside_ the type. for a similar macro that can be defined _outside_ the type.
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. - [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview.
@ -124,3 +153,4 @@ See examples below for the concrete generated code.
1. Added in version 3.9.0. 1. Added in version 3.9.0.
2. Added in version 3.11.0. 2. Added in version 3.11.0.
3. Added in version TODO.

View File

@ -1,8 +1,9 @@
# NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT # NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE
```cpp ```cpp
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) // (1) #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) // (1)
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3)
``` ```
These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as
@ -16,6 +17,7 @@ parameter is the name of the class/struct, and all remaining parameters name the
2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the 2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the
respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function
default constructs an object and uses its values as the defaults when calling the `value` function. default constructs an object and uses its values as the defaults when calling the `value` function.
3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization in required.
## Parameters ## Parameters
@ -31,7 +33,7 @@ The macros add two functions to the namespace which take care of the serializati
```cpp ```cpp
void to_json(nlohmann::json&, const type&); void to_json(nlohmann::json&, const type&);
void from_json(const nlohmann::json&, type&); void from_json(const nlohmann::json&, type&); // except (3)
``` ```
See examples below for the concrete generated code. See examples below for the concrete generated code.
@ -40,7 +42,7 @@ See examples below for the concrete generated code.
!!! info "Prerequisites" !!! info "Prerequisites"
1. The type `type` must be default constructible. See [How can I use `get()` for non-default constructible/non-copyable types?][GetNonDefNonCopy] 1. The type `type` must be default constructible (except (3). See [How can I use `get()` for non-default constructible/non-copyable types?][GetNonDefNonCopy]
for how to overcome this limitation. for how to overcome this limitation.
2. The macro must be used outside the type (class/struct). 2. The macro must be used outside the type (class/struct).
3. The passed members must be public. 3. The passed members must be public.
@ -88,7 +90,7 @@ See examples below for the concrete generated code.
Consider the following complete example: Consider the following complete example:
```cpp hl_lines="21" ```cpp hl_lines="22"
--8<-- "examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp" --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp"
``` ```
@ -109,15 +111,42 @@ See examples below for the concrete generated code.
The macro is equivalent to: The macro is equivalent to:
```cpp hl_lines="21 22 23 24 25 26 27 28 29 30 31 32 33 34" ```cpp hl_lines="22 23 24 25 26 27 28 29 30 31 32 33 34 35"
--8<-- "examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp" --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp"
``` ```
Note how a default-initialized `person` object is used in the `from_json` to fill missing values. Note how a default-initialized `person` object is used in the `from_json` to fill missing values.
??? example "Example (3): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE"
Consider the following complete example:
```cpp hl_lines="16"
--8<-- "examples/nlohmann_define_type_non_intrusive_only_serialize_macro.cpp"
```
Output:
```json
--8<-- "examples/nlohmann_define_type_non_intrusive_only_serialize_macro.output"
```
Notes:
- `ns::person` is non-default-constructible. This allows this macro to be used instead of
`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` and `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`.
- `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` applicable.
- The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` is used _outside_ the class, but _inside_ its namespace `ns`.
The macro is equivalent to:
```cpp hl_lines="16 17 18 19 20 21"
--8<-- "examples/nlohmann_define_type_non_intrusive_only_serialize_explicit.cpp"
```
## See also ## See also
- [NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_intrusive.md) - [NLOHMANN_DEFINE_TYPE_INTRUSIVE{_WITH_DEFAULT, _ONLY_SERIALIZE}](nlohmann_define_type_intrusive.md)
for a similar macro that can be defined _inside_ the type. for a similar macro that can be defined _inside_ the type.
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. - [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview.
@ -125,3 +154,4 @@ See examples below for the concrete generated code.
1. Added in version 3.9.0. 1. Added in version 3.9.0.
2. Added in version 3.11.0. 2. Added in version 3.11.0.
3. Added in version TODO.

View File

@ -119,6 +119,13 @@ an object and uses its values as the defaults when calling the [`value`](../api/
See [full documentation of `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT`](../api/macros/nlohmann_define_type_intrusive.md). See [full documentation of `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT`](../api/macros/nlohmann_define_type_intrusive.md).
## `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, member...)`
This macro is similar to `NLOHMANN_DEFINE_TYPE_INTRUSIVE` except that it defines only the serialization code. This is
useful when the user type does not have a default constructor and only the serialization is required.
See [full documentation of `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE`](../api/macros//nlohmann_define_type_intrusive.md).
## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)` ## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)`
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as
@ -138,6 +145,13 @@ an object and uses its values as the defaults when calling the [`value`](../api/
See [full documentation of `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`](../api/macros/nlohmann_define_type_non_intrusive.md). See [full documentation of `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`](../api/macros/nlohmann_define_type_non_intrusive.md).
## `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, member...)`
This macro is similar to `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` except that it defines only the serialization code. This is
useful when the user type does not have a default constructor and only the serialization is required.
See [full documentation of `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE`](../api/macros//nlohmann_define_type_non_intrusive.md).
## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)` ## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)`
This macro simplifies the serialization/deserialization of enum types. See This macro simplifies the serialization/deserialization of enum types. See

View File

@ -406,6 +406,9 @@
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 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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(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__)) }
/*! /*!
@brief macro @brief macro
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
@ -415,6 +418,9 @@
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 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__)) } 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_ONLY_SERIALIZE(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__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ #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 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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }

View File

@ -2758,6 +2758,9 @@ JSON_HEDLEY_DIAGNOSTIC_POP
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 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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(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__)) }
/*! /*!
@brief macro @brief macro
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
@ -2767,6 +2770,9 @@ JSON_HEDLEY_DIAGNOSTIC_POP
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 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__)) } 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_ONLY_SERIALIZE(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__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ #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 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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }

View File

@ -279,6 +279,44 @@ class person_with_public_alphabet
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
class person_without_default_constructor_1
{
public:
std::string name;
int age;
bool operator==(const person_without_default_constructor_1& other) const
{
return name == other.name && age == other.age;
}
person_without_default_constructor_1(std::string name_, int age_)
: name{std::move(name_)}
, age{age_}
{}
NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(person_without_default_constructor_1, name, age)
};
class person_without_default_constructor_2
{
public:
std::string name;
int age;
bool operator==(const person_without_default_constructor_2& other) const
{
return name == other.name && age == other.age;
}
person_without_default_constructor_2(std::string name_, int age_)
: name{std::move(name_)}
, age{age_}
{}
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(person_without_default_constructor_2, name, age)
} // namespace persons } // namespace persons
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T, TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
@ -412,3 +450,25 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
} }
} }
} }
TEST_CASE_TEMPLATE("Serialization of non-default-constructible classes via NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE", T,
persons::person_without_default_constructor_1,
persons::person_without_default_constructor_2)
{
SECTION("person")
{
{
// serialization of a single object
T person{"Erik", 1};
CHECK(json(person).dump() == "{\"age\":1,\"name\":\"Erik\"}");
// serialization of a container with objects
std::vector<T> const two_persons
{
{"Erik", 1},
{"Kyle", 2}
};
CHECK(json(two_persons).dump() == "[{\"age\":1,\"name\":\"Erik\"},{\"age\":2,\"name\":\"Kyle\"}]");
}
}
}