diff --git a/docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md b/docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md index a892e690e..1b638c99d 100644 --- a/docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md +++ b/docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md @@ -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 +friend void to_json(BasicJsonType&, const type&); +template +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 +void to_json(BasicJsonType&, const type&); +template +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 +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 +void to_json(BasicJsonType& j, const B& b) { nlohmann::to_json(j, static_cast(b)); // ... } -void from_json(const nlohmann::json& j, B& b) { +template +void from_json(const BasicJsonType& j, B& b) { nlohmann::from_json(j, static_cast(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 +void to_json(BasicJsonType& j, const B& b) { nlohmann::to_json(j, static_cast(b)); // ... } diff --git a/docs/mkdocs/docs/api/macros/nlohmann_define_type_intrusive.md b/docs/mkdocs/docs/api/macros/nlohmann_define_type_intrusive.md index a1c826579..488681ea2 100644 --- a/docs/mkdocs/docs/api/macros/nlohmann_define_type_intrusive.md +++ b/docs/mkdocs/docs/api/macros/nlohmann_define_type_intrusive.md @@ -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 +friend void to_json(BasicJsonType&, const type&); +template +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" ``` diff --git a/docs/mkdocs/docs/api/macros/nlohmann_define_type_non_intrusive.md b/docs/mkdocs/docs/api/macros/nlohmann_define_type_non_intrusive.md index c907c7609..49c3ac642 100644 --- a/docs/mkdocs/docs/api/macros/nlohmann_define_type_non_intrusive.md +++ b/docs/mkdocs/docs/api/macros/nlohmann_define_type_non_intrusive.md @@ -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 +void to_json(BasicJsonType&, const type&); +template +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" ``` diff --git a/docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md b/docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md index dc2cc8ecb..e615e65be 100644 --- a/docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md +++ b/docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md @@ -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 diff --git a/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_explicit.cpp b/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_explicit.cpp index de79bd37c..e2021e235 100644 --- a/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_explicit.cpp +++ b/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_explicit.cpp @@ -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 + 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 + 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"); diff --git a/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_only_serialize_explicit.cpp b/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_only_serialize_explicit.cpp index ea422beb5..dd6a9a679 100644 --- a/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_only_serialize_explicit.cpp +++ b/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_only_serialize_explicit.cpp @@ -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 + 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; diff --git a/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp b/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp index 0fb2e1cb2..397795576 100644 --- a/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp +++ b/docs/mkdocs/docs/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp @@ -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 + 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 + 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); diff --git a/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_explicit.cpp b/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_explicit.cpp index a31a7eb8f..9f5cdc173 100644 --- a/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_explicit.cpp +++ b/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_explicit.cpp @@ -13,14 +13,16 @@ struct person int age; }; -void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t) +template +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 +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"); diff --git a/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_only_serialize_explicit.cpp b/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_only_serialize_explicit.cpp index 8890e03af..ead75b74e 100644 --- a/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_only_serialize_explicit.cpp +++ b/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_only_serialize_explicit.cpp @@ -13,7 +13,8 @@ struct person int age; }; -void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t) +template +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; diff --git a/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp b/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp index 855ab52b8..1bdd25ed9 100644 --- a/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp +++ b/docs/mkdocs/docs/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp @@ -18,14 +18,16 @@ struct person {} }; -void to_json(nlohmann::json& nlohmann_json_j, const person& nlohmann_json_t) +template +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 +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); diff --git a/docs/mkdocs/docs/features/arbitrary_types.md b/docs/mkdocs/docs/features/arbitrary_types.md index fba7e656d..63c4f8ac9 100644 --- a/docs/mkdocs/docs/features/arbitrary_types.md +++ b/docs/mkdocs/docs/features/arbitrary_types.md @@ -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 diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index 7e6325769..a399986fc 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -404,8 +404,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(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) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -414,8 +416,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& 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__)) } /*! @brief macro @@ -424,7 +428,8 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #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__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @@ -433,8 +438,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(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) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -443,8 +450,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& 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__)) } /*! @brief macro @@ -453,7 +462,8 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #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__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @@ -462,8 +472,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -472,8 +484,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @@ -482,7 +496,8 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @@ -491,8 +506,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -501,8 +518,10 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @@ -511,7 +530,8 @@ @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } // inspired from https://stackoverflow.com/a/26745591 // allows to call any std function as if (e.g. with begin): diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 9339c7b28..704b2189d 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -2770,8 +2770,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(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) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -2780,8 +2782,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& 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__)) } /*! @brief macro @@ -2790,7 +2794,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #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__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @@ -2799,8 +2804,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(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) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -2809,8 +2816,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& 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__)) } /*! @brief macro @@ -2819,7 +2828,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #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__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @@ -2828,8 +2838,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -2838,8 +2850,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @@ -2848,7 +2862,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @@ -2857,8 +2872,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @@ -2867,8 +2884,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(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::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @@ -2877,7 +2896,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } // inspired from https://stackoverflow.com/a/26745591 // allows to call any std function as if (e.g. with begin): diff --git a/tests/src/unit-udt_macro.cpp b/tests/src/unit-udt_macro.cpp index 8a71d4483..0be6b5924 100644 --- a/tests/src/unit-udt_macro.cpp +++ b/tests/src/unit-udt_macro.cpp @@ -326,19 +326,6 @@ class person_with_private_alphabet NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_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 derived_person_with_private_alphabet : public person_with_private_alphabet -{ - public: - bool operator==(const derived_person_with_private_alphabet& other) const - { - return person_with_private_alphabet::operator==(other) && schwa == other.schwa; - } - - private: - int schwa = 0; - NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived_person_with_private_alphabet, person_with_private_alphabet, schwa) -}; - class person_with_public_alphabet { public: @@ -468,128 +455,166 @@ class derived_person_only_serialize_private : person_without_default_constructor } // namespace persons -TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T, // NOLINT(readability-math-missing-parentheses) - persons::person_with_private_data, - persons::person_without_private_data_1, - persons::person_without_private_data_2) +TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", Pair, // NOLINT(readability-math-missing-parentheses) + std::pair, + std::pair, + std::pair, + std::pair, + std::pair, + std::pair) { + using Json = typename Pair::first_type; + using T = typename Pair::second_type; + constexpr bool is_ordered = std::is_same::value; + SECTION("person") { // serialization T p1("Erik", 1, {{"haircuts", 2}}); - CHECK(json(p1).dump() == "{\"age\":1,\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}"); + CHECK(Json(p1).dump() == (is_ordered ? + R"({"age":1,"name":"Erik","metadata":{"haircuts":2}})" : + R"({"age":1,"metadata":{"haircuts":2},"name":"Erik"})")); // deserialization - auto p2 = json(p1).get(); + auto p2 = Json(p1).template get(); CHECK(p2 == p1); // roundtrip - CHECK(T(json(p1)) == p1); - CHECK(json(T(json(p1))) == json(p1)); + CHECK(T(Json(p1)) == p1); + CHECK(Json(T(Json(p1))) == Json(p1)); // check exception in case of missing field - json j = json(p1); + Json j = Json(p1); j.erase("age"); - CHECK_THROWS_WITH_AS(j.get(), "[json.exception.out_of_range.403] key 'age' not found", json::out_of_range); + CHECK_THROWS_WITH_AS(j.template get(), "[json.exception.out_of_range.403] key 'age' not found", typename Json::out_of_range); } } -TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE", T, // NOLINT(readability-math-missing-parentheses) - persons::derived_person_with_private_data, - persons::derived_person_without_private_data_1, - persons::derived_person_without_private_data_2) +TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE", Pair, // NOLINT(readability-math-missing-parentheses) + std::pair, + std::pair, + std::pair, + std::pair, + std::pair, + std::pair) { + using Json = typename Pair::first_type; + using T = typename Pair::second_type; + constexpr bool is_ordered = std::is_same::value; + SECTION("person") { // serialization T p1("Erik", 1, {{"haircuts", 2}}, "red"); - CHECK(json(p1).dump() == "{\"age\":1,\"hair_color\":\"red\",\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}"); + CHECK(Json(p1).dump() == (is_ordered ? + R"({"age":1,"name":"Erik","metadata":{"haircuts":2},"hair_color":"red"})" : + R"({"age":1,"hair_color":"red","metadata":{"haircuts":2},"name":"Erik"})")); // deserialization - auto p2 = json(p1).get(); + auto p2 = Json(p1).template get(); CHECK(p2 == p1); // roundtrip - CHECK(T(json(p1)) == p1); - CHECK(json(T(json(p1))) == json(p1)); + CHECK(T(Json(p1)) == p1); + CHECK(Json(T(Json(p1))) == Json(p1)); // check exception in case of missing field - json j = json(p1); + Json j = Json(p1); j.erase("age"); - CHECK_THROWS_WITH_AS(j.get(), "[json.exception.out_of_range.403] key 'age' not found", json::out_of_range); + CHECK_THROWS_WITH_AS(j.template get(), "[json.exception.out_of_range.403] key 'age' not found", typename Json::out_of_range); } } -TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T, // NOLINT(readability-math-missing-parentheses) - persons::person_with_private_data_2, - persons::person_without_private_data_3) +TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT", Pair, // NOLINT(readability-math-missing-parentheses) + std::pair, + std::pair, + std::pair, + std::pair) { + using Json = typename Pair::first_type; + using T = typename Pair::second_type; + constexpr bool is_ordered = std::is_same::value; + SECTION("person with default values") { // serialization of default constructed object - T p0; - CHECK(json(p0).dump() == "{\"age\":0,\"metadata\":null,\"name\":\"\"}"); + const T p0{}; + CHECK(Json(p0).dump() == (is_ordered ? + R"({"age":0,"name":"","metadata":null})" : + R"({"age":0,"metadata":null,"name":""})")); // serialization T p1("Erik", 1, {{"haircuts", 2}}); - CHECK(json(p1).dump() == "{\"age\":1,\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}"); + CHECK(Json(p1).dump() == (is_ordered ? + R"({"age":1,"name":"Erik","metadata":{"haircuts":2}})" : + R"({"age":1,"metadata":{"haircuts":2},"name":"Erik"})")); // deserialization - auto p2 = json(p1).get(); + auto p2 = Json(p1).template get(); CHECK(p2 == p1); // roundtrip - CHECK(T(json(p1)) == p1); - CHECK(json(T(json(p1))) == json(p1)); + CHECK(T(Json(p1)) == p1); + CHECK(Json(T(Json(p1))) == Json(p1)); // check default value in case of missing field - json j = json(p1); + Json j = Json(p1); j.erase("name"); j.erase("age"); j.erase("metadata"); - T p3 = j.get(); + const T p3 = j.template get(); CHECK(p3.getName() == ""); CHECK(p3.getAge() == 0); CHECK(p3.getMetadata() == nullptr); // check default value in case of empty json - const json j4; - T p4 = j4.get(); + const Json j4; + const T p4 = j4.template get(); CHECK(p4.getName() == ""); CHECK(p4.getAge() == 0); CHECK(p4.getMetadata() == nullptr); } } -TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T, // NOLINT(readability-math-missing-parentheses) - persons::derived_person_with_private_data_2, - persons::derived_person_without_private_data_3) +TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT", Pair, // NOLINT(readability-math-missing-parentheses) + std::pair, + std::pair, + std::pair, + std::pair) { + using Json = typename Pair::first_type; + using T = typename Pair::second_type; + constexpr bool is_ordered = std::is_same::value; + SECTION("derived person with default values") { // serialization of default constructed object - T p0; - CHECK(json(p0).dump() == "{\"age\":0,\"hair_color\":\"blue\",\"metadata\":null,\"name\":\"\"}"); + const T p0{}; + CHECK(Json(p0).dump() == (is_ordered ? + R"({"age":0,"name":"","metadata":null,"hair_color":"blue"})" : + R"({"age":0,"hair_color":"blue","metadata":null,"name":""})")); // serialization T p1("Erik", 1, {{"haircuts", 2}}, "red"); - CHECK(json(p1).dump() == "{\"age\":1,\"hair_color\":\"red\",\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}"); + CHECK(Json(p1).dump() == (is_ordered ? + R"({"age":1,"name":"Erik","metadata":{"haircuts":2},"hair_color":"red"})" : + R"({"age":1,"hair_color":"red","metadata":{"haircuts":2},"name":"Erik"})")); // deserialization - auto p2 = json(p1).get(); + auto p2 = Json(p1).template get(); CHECK(p2 == p1); // roundtrip - CHECK(T(json(p1)) == p1); - CHECK(json(T(json(p1))) == json(p1)); + CHECK(T(Json(p1)) == p1); + CHECK(Json(T(Json(p1))) == Json(p1)); // check default value in case of missing field - json j = json(p1); + Json j = Json(p1); j.erase("name"); j.erase("age"); j.erase("metadata"); j.erase("hair_color"); - T p3 = j.get(); + const T p3 = j.template get(); CHECK(p3.getName() == ""); CHECK(p3.getAge() == 0); CHECK(p3.getMetadata() == nullptr); @@ -597,118 +622,81 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TY } } -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, // NOLINT(readability-math-missing-parentheses) - persons::person_with_private_alphabet, - persons::person_with_public_alphabet) +TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", Pair, // NOLINT(readability-math-missing-parentheses) + std::pair, + std::pair, + std::pair, + std::pair) { + using Json = typename Pair::first_type; + using T = typename Pair::second_type; + SECTION("alphabet") { - { - T obj1; - nlohmann::json const j = obj1; //via json object - T obj2; - j.get_to(obj2); - bool ok = (obj1 == obj2); - CHECK(ok); - } - - { - T obj1; - nlohmann::json const j1 = obj1; //via json string - std::string const s = j1.dump(); - nlohmann::json const j2 = nlohmann::json::parse(s); - T obj2; - j2.get_to(obj2); - bool ok = (obj1 == obj2); - CHECK(ok); - } - - { - T obj1; - nlohmann::json const j1 = obj1; //via msgpack - std::vector const buf = nlohmann::json::to_msgpack(j1); - nlohmann::json const j2 = nlohmann::json::from_msgpack(buf); - T obj2; - j2.get_to(obj2); - bool ok = (obj1 == obj2); - CHECK(ok); - } - - { - T obj1; - nlohmann::json const j1 = obj1; //via bson - std::vector const buf = nlohmann::json::to_bson(j1); - nlohmann::json const j2 = nlohmann::json::from_bson(buf); - T obj2; - j2.get_to(obj2); - bool ok = (obj1 == obj2); - CHECK(ok); - } - - { - T obj1; - nlohmann::json const j1 = obj1; //via cbor - std::vector const buf = nlohmann::json::to_cbor(j1); - nlohmann::json const j2 = nlohmann::json::from_cbor(buf); - T obj2; - j2.get_to(obj2); - bool ok = (obj1 == obj2); - CHECK(ok); - } - - { - T obj1; - nlohmann::json const j1 = obj1; //via ubjson - std::vector const buf = nlohmann::json::to_ubjson(j1); - nlohmann::json const j2 = nlohmann::json::from_ubjson(buf); - T obj2; - j2.get_to(obj2); - bool ok = (obj1 == obj2); - CHECK(ok); - } + T obj1; + Json const j = obj1; + T obj2; + j.get_to(obj2); + CHECK(obj1 == obj2); } } -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, // NOLINT(readability-math-missing-parentheses) - persons::person_without_default_constructor_1, - persons::person_without_default_constructor_2) +TEST_CASE_TEMPLATE("Serialization of non-default-constructible classes via NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE", Pair, // NOLINT(readability-math-missing-parentheses) + std::pair, + std::pair, + std::pair, + std::pair) { + using Json = typename Pair::first_type; + using T = typename Pair::second_type; + constexpr bool is_ordered = std::is_same::value; + SECTION("person") { - { - // serialization of a single object - T person{"Erik", 1}; - CHECK(json(person).dump() == "{\"age\":1,\"name\":\"Erik\"}"); + // serialization of a single object + const T person{"Erik", 1}; + CHECK(Json(person).dump() == (is_ordered ? + R"({"name":"Erik","age":1})" : + R"({"age":1,"name":"Erik"})")); - // serialization of a container with objects - std::vector const two_persons - { - {"Erik", 1}, - {"Kyle", 2} - }; - CHECK(json(two_persons).dump() == "[{\"age\":1,\"name\":\"Erik\"},{\"age\":2,\"name\":\"Kyle\"}]"); - } + // serialization of a container with objects + std::vector const two_persons + { + {"Erik", 1}, + {"Kyle", 2} + }; + CHECK(Json(two_persons).dump() == (is_ordered ? + R"([{"name":"Erik","age":1},{"name":"Kyle","age":2}])" : + R"([{"age":1,"name":"Erik"},{"age":2,"name":"Kyle"}])")); } } -TEST_CASE_TEMPLATE("Serialization of non-default-constructible classes via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE", T, // NOLINT(readability-math-missing-parentheses) - persons::derived_person_only_serialize_public, - persons::derived_person_only_serialize_private) +TEST_CASE_TEMPLATE("Serialization of non-default-constructible classes via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE", Pair, // NOLINT(readability-math-missing-parentheses) + std::pair, + std::pair, + std::pair, + std::pair) { + using Json = typename Pair::first_type; + using T = typename Pair::second_type; + constexpr bool is_ordered = std::is_same::value; + SECTION("derived person only serialize") { - { - // serialization of a single object - T person{"Erik", 1, "brown"}; - CHECK(json(person).dump() == "{\"age\":1,\"hair_color\":\"brown\",\"name\":\"Erik\"}"); + // serialization of a single object + const T person{"Erik", 1, "brown"}; + CHECK(Json(person).dump() == (is_ordered ? + R"({"name":"Erik","age":1,"hair_color":"brown"})" : + R"({"age":1,"hair_color":"brown","name":"Erik"})")); - // serialization of a container with objects - std::vector const two_persons - { - {"Erik", 1, "brown"}, - {"Kyle", 2, "black"} - }; - CHECK(json(two_persons).dump() == "[{\"age\":1,\"hair_color\":\"brown\",\"name\":\"Erik\"},{\"age\":2,\"hair_color\":\"black\",\"name\":\"Kyle\"}]"); - } + // serialization of a container with objects + std::vector const two_persons + { + {"Erik", 1, "brown"}, + {"Kyle", 2, "black"} + }; + CHECK(Json(two_persons).dump() == (is_ordered ? + R"([{"name":"Erik","age":1,"hair_color":"brown"},{"name":"Kyle","age":2,"hair_color":"black"}])" : + R"([{"age":1,"hair_color":"brown","name":"Erik"},{"age":2,"hair_color":"black","name":"Kyle"}])")); } }