Add docs for serialization-only user defined type macros

This commit is contained in:
Vyacheslav Zhdanovskiy 2023-10-02 11:48:50 +03:00
parent 7aca5e6076
commit 1b727051c7
11 changed files with 202 additions and 10 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,9 @@ 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).
@ -114,9 +116,36 @@ See examples below for the concrete generated code.
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="21"
--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="21 22 23 24 25 26"
--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.
@ -115,9 +117,36 @@ See examples below for the concrete generated code.
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="15"
--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="15 16 17 18 19 20"
--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.