mirror of
https://github.com/nlohmann/json.git
synced 2025-11-24 11:54:34 +08:00
Generate template functions with NLOHMANN_DEFINE_TYPE macros (#4597)
* Support any basic_json type in NLOHMANN_DEFINE_TYPE_* macros Signed-off-by: kimci86 <kimci86@hotmail.fr> * Test NLOHMANN_DEFINE_TYPE_* macros also support unordered_json Signed-off-by: kimci86 <kimci86@hotmail.fr> * Simplify test about NLOHMANN_DEFINE_TYPE_ with many arguments Signed-off-by: kimci86 <kimci86@hotmail.fr> * Remove extra scope in macros tests Signed-off-by: kimci86 <kimci86@hotmail.fr> * Remove unused test class in macros tests Signed-off-by: kimci86 <kimci86@hotmail.fr> * Update documentation about NLOHMANN_DEFINE_TYPE_* macros Signed-off-by: kimci86 <kimci86@hotmail.fr> * Fix NLOHMANN_JSON_SERIALIZE_ENUM documentation Signed-off-by: kimci86 <kimci86@hotmail.fr> * Mark some variables const in macros tests, fixes clang-tidy Signed-off-by: kimci86 <kimci86@hotmail.fr> * Workaround clang 3.5 issue with const object initialization Signed-off-by: kimci86 <kimci86@hotmail.fr> * Update highlighted lines in NLOHMANN_DEFINE_TYPE_* macros examples Signed-off-by: kimci86 <kimci86@hotmail.fr> * Fix swapped macros in documentation Signed-off-by: kimci86 <kimci86@hotmail.fr> * Remove extra backslashes at the end of macros Signed-off-by: kimci86 <kimci86@hotmail.fr> * Require basic_json type in NLOHMANN_DEFINE_TYPE_* generated functions Signed-off-by: kimci86 <kimci86@hotmail.fr> * Fix typos in macros documentation Signed-off-by: kimci86 <kimci86@hotmail.fr> --------- Signed-off-by: kimci86 <kimci86@hotmail.fr>
This commit is contained in:
@@ -64,21 +64,26 @@ Summary:
|
||||
Macros 1 and 2 add two friend functions to the class which take care of the serialization and deserialization:
|
||||
|
||||
```cpp
|
||||
friend void to_json(nlohmann::json&, const type&);
|
||||
friend void from_json(const nlohmann::json&, type&);
|
||||
template<typename BasicJsonType>
|
||||
friend void to_json(BasicJsonType&, const type&);
|
||||
template<typename BasicJsonType>
|
||||
friend void from_json(const BasicJsonType&, type&);
|
||||
```
|
||||
|
||||
Macros 4 and 5 add two functions to the namespace which take care of the serialization and deserialization:
|
||||
|
||||
```cpp
|
||||
void to_json(nlohmann::json&, const type&);
|
||||
void from_json(const nlohmann::json&, type&);
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType&, const type&);
|
||||
template<typename BasicJsonType>
|
||||
void from_json(const BasicJsonType&, type&);
|
||||
```
|
||||
|
||||
Macros 3 and 6 add one function to the namespace which take care of the serialization only:
|
||||
|
||||
```cpp
|
||||
void to_json(nlohmann::json&, const type&);
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType&, const type&);
|
||||
```
|
||||
|
||||
In first two cases, they call the `to_json`/`from_json` functions of the base type
|
||||
@@ -88,12 +93,14 @@ before serializing/deserializing the members of the derived type:
|
||||
class A { /* ... */ };
|
||||
class B : public A { /* ... */ };
|
||||
|
||||
void to_json(nlohmann::json& j, const B& b) {
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType& j, const B& b) {
|
||||
nlohmann::to_json(j, static_cast<const A&>(b));
|
||||
// ...
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& j, B& b) {
|
||||
template<typename BasicJsonType>
|
||||
void from_json(const BasicJsonType& j, B& b) {
|
||||
nlohmann::from_json(j, static_cast<A&>(b));
|
||||
// ...
|
||||
}
|
||||
@@ -105,7 +112,8 @@ In the third case, only `to_json` will be called:
|
||||
class A { /* ... */ };
|
||||
class B : public A { /* ... */ };
|
||||
|
||||
void to_json(nlohmann::json& j, const B& b) {
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType& j, const B& b) {
|
||||
nlohmann::to_json(j, static_cast<const A&>(b));
|
||||
// ...
|
||||
}
|
||||
|
||||
@@ -40,8 +40,10 @@ Summary:
|
||||
The macros add two friend functions to the class which take care of the serialization and deserialization:
|
||||
|
||||
```cpp
|
||||
friend void to_json(nlohmann::json&, const type&);
|
||||
friend void from_json(const nlohmann::json&, type&); // except (3)
|
||||
template<typename BasicJsonType>
|
||||
friend void to_json(BasicJsonType&, const type&);
|
||||
template<typename BasicJsonType>
|
||||
friend void from_json(const BasicJsonType&, type&); // except (3)
|
||||
```
|
||||
|
||||
See examples below for the concrete generated code.
|
||||
@@ -60,8 +62,6 @@ See examples below for the concrete generated code.
|
||||
|
||||
- The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types
|
||||
with more than 64 member variables, you need to define the `to_json`/`from_json` functions manually.
|
||||
- The macros only work for the [`nlohmann::json`](../json.md) type; other specializations such as
|
||||
[`nlohmann::ordered_json`](../ordered_json.md) are currently unsupported.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -90,7 +90,7 @@ See examples below for the concrete generated code.
|
||||
|
||||
The macro is equivalent to:
|
||||
|
||||
```cpp hl_lines="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 36"
|
||||
--8<-- "examples/nlohmann_define_type_intrusive_explicit.cpp"
|
||||
```
|
||||
|
||||
@@ -118,7 +118,7 @@ See examples below for the concrete generated code.
|
||||
|
||||
The macro is equivalent to:
|
||||
|
||||
```cpp hl_lines="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 36 37"
|
||||
--8<-- "examples/nlohmann_define_type_intrusive_with_default_explicit.cpp"
|
||||
```
|
||||
|
||||
@@ -147,7 +147,7 @@ See examples below for the concrete generated code.
|
||||
|
||||
The macro is equivalent to:
|
||||
|
||||
```cpp hl_lines="22 22 23 24 25 26 27"
|
||||
```cpp hl_lines="22 22 23 24 25 26 27 28"
|
||||
--8<-- "examples/nlohmann_define_type_intrusive_only_serialize_explicit.cpp"
|
||||
```
|
||||
|
||||
|
||||
@@ -40,8 +40,10 @@ Summary:
|
||||
The macros add two functions to the namespace which take care of the serialization and deserialization:
|
||||
|
||||
```cpp
|
||||
void to_json(nlohmann::json&, const type&);
|
||||
void from_json(const nlohmann::json&, type&); // except (3)
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType&, const type&);
|
||||
template<typename BasicJsonType>
|
||||
void from_json(const BasicJsonType&, type&); // except (3)
|
||||
```
|
||||
|
||||
See examples below for the concrete generated code.
|
||||
@@ -61,8 +63,6 @@ See examples below for the concrete generated code.
|
||||
|
||||
- The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types
|
||||
with more than 64 member variables, you need to define the `to_json`/`from_json` functions manually.
|
||||
- The macros only work for the [`nlohmann::json`](../json.md) type; other specializations such as
|
||||
[`nlohmann::ordered_json`](../ordered_json.md) are currently unsupported.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -90,7 +90,7 @@ See examples below for the concrete generated code.
|
||||
|
||||
The macro is equivalent to:
|
||||
|
||||
```cpp hl_lines="16 17 18 19 20 21 22 23 24 25 26 27 28"
|
||||
```cpp hl_lines="16 17 18 19 20 21 22 23 24 25 26 27 28 29 30"
|
||||
--8<-- "examples/nlohmann_define_type_non_intrusive_explicit.cpp"
|
||||
```
|
||||
|
||||
@@ -98,7 +98,7 @@ See examples below for the concrete generated code.
|
||||
|
||||
Consider the following complete example:
|
||||
|
||||
```cpp hl_lines="22"
|
||||
```cpp hl_lines="21"
|
||||
--8<-- "examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp"
|
||||
```
|
||||
|
||||
@@ -119,7 +119,7 @@ See examples below for the concrete generated code.
|
||||
|
||||
The macro is equivalent to:
|
||||
|
||||
```cpp hl_lines="22 23 24 25 26 27 28 29 30 31 32 33 34 35"
|
||||
```cpp hl_lines="21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36"
|
||||
--8<-- "examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp"
|
||||
```
|
||||
|
||||
@@ -148,7 +148,7 @@ See examples below for the concrete generated code.
|
||||
|
||||
The macro is equivalent to:
|
||||
|
||||
```cpp hl_lines="16 17 18 19 20 21"
|
||||
```cpp hl_lines="16 17 18 19 20 21 22"
|
||||
--8<-- "examples/nlohmann_define_type_non_intrusive_only_serialize_explicit.cpp"
|
||||
```
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ The `NLOHMANN_JSON_SERIALIZE_ENUM` allows to define a user-defined serialization
|
||||
|
||||
## Default definition
|
||||
|
||||
The macros add two friend functions to the class which take care of the serialization and deserialization:
|
||||
The macro adds two functions to the namespace which take care of the serialization and deserialization:
|
||||
|
||||
```cpp
|
||||
template<typename BasicJsonType>
|
||||
|
||||
@@ -19,14 +19,16 @@ class person
|
||||
: name(std::move(name_)), address(std::move(address_)), age(age_)
|
||||
{}
|
||||
|
||||
friend void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
friend void to_json(BasicJsonType& 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;
|
||||
}
|
||||
|
||||
friend void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)
|
||||
{
|
||||
nlohmann_json_t.name = nlohmann_json_j.at("name");
|
||||
nlohmann_json_t.address = nlohmann_json_j.at("address");
|
||||
|
||||
@@ -19,7 +19,8 @@ class person
|
||||
: name(std::move(name_)), address(std::move(address_)), age(age_)
|
||||
{}
|
||||
|
||||
friend void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
{
|
||||
nlohmann_json_j["name"] = nlohmann_json_t.name;
|
||||
nlohmann_json_j["address"] = nlohmann_json_t.address;
|
||||
|
||||
@@ -19,14 +19,16 @@ class person
|
||||
: name(std::move(name_)), address(std::move(address_)), age(age_)
|
||||
{}
|
||||
|
||||
friend void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
friend void to_json(BasicJsonType& 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;
|
||||
}
|
||||
|
||||
friend void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)
|
||||
{
|
||||
person nlohmann_json_default_obj;
|
||||
nlohmann_json_t.name = nlohmann_json_j.value("name", nlohmann_json_default_obj.name);
|
||||
|
||||
@@ -13,14 +13,16 @@ struct person
|
||||
int age;
|
||||
};
|
||||
|
||||
void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType& 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;
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)
|
||||
{
|
||||
nlohmann_json_t.name = nlohmann_json_j.at("name");
|
||||
nlohmann_json_t.address = nlohmann_json_j.at("address");
|
||||
|
||||
@@ -13,7 +13,8 @@ struct person
|
||||
int age;
|
||||
};
|
||||
|
||||
void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
{
|
||||
nlohmann_json_j["name"] = nlohmann_json_t.name;
|
||||
nlohmann_json_j["address"] = nlohmann_json_t.address;
|
||||
|
||||
@@ -18,14 +18,16 @@ struct person
|
||||
{}
|
||||
};
|
||||
|
||||
void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
void to_json(BasicJsonType& 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;
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& nlohmann_json_j, person& nlohmann_json_t)
|
||||
template<typename BasicJsonType>
|
||||
void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)
|
||||
{
|
||||
person nlohmann_json_default_obj;
|
||||
nlohmann_json_t.name = nlohmann_json_j.value("name", nlohmann_json_default_obj.name);
|
||||
|
||||
@@ -89,10 +89,10 @@ There are six macros to make your life easier as long as you (1) want to use a J
|
||||
|
||||
- [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_non_intrusive.md) is to be defined inside the namespace of the class/struct to create code for. It will throw an exception in `from_json()` due to a missing value in the JSON object.
|
||||
- [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_non_intrusive.md) is to be defined inside the namespace of the class/struct to create code for. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type.
|
||||
- [`NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_non_intrusive.md) is to be defined inside the namespace of the class/struct to create code for. It does not define a `fron_json()` function which is needed in case the type does not have a default constructor.
|
||||
- [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_non_intrusive.md) is to be defined inside the namespace of the class/struct to create code for. It does not define a `from_json()` function which is needed in case the type does not have a default constructor.
|
||||
- [`NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_intrusive.md) is to be defined inside the class/struct to create code for. This macro can also access private members. It will throw an exception in `from_json()` due to a missing value in the JSON object.
|
||||
- [`NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_intrusive.md) is to be defined inside the class/struct to create code for. This macro can also access private members. It will not throw an exception in `from_json()` due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type.
|
||||
- [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_intrusive.md) is to be defined inside the class/struct to create code for. This macro can also access private members. It does not define a `fron_json()` function which is needed in case the type does not have a default constructor.
|
||||
- [`NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(name, member1, member2, ...)`](../api/macros/nlohmann_define_type_intrusive.md) is to be defined inside the class/struct to create code for. This macro can also access private members. It does not define a `from_json()` function which is needed in case the type does not have a default constructor.
|
||||
|
||||
Furthermore, there exist versions to use in case of derived classes:
|
||||
|
||||
@@ -120,8 +120,6 @@ For _derived_ classes and structs, use the following macros
|
||||
|
||||
- The current macro implementations are limited to at most 64 member variables. If you want to serialize/deserialize
|
||||
types with more than 64 member variables, you need to define the `to_json`/`from_json` functions manually.
|
||||
- The macros only work for the [`nlohmann::json`](../api/json.md) type; other specializations such as
|
||||
[`nlohmann::ordered_json`](../api/ordered_json.md) are currently unsupported.
|
||||
|
||||
??? example
|
||||
|
||||
|
||||
Reference in New Issue
Block a user