This commit is contained in:
Niccolò Iardella 2023-11-02 12:33:11 +01:00 committed by GitHub
commit 77de96348f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 704 additions and 307 deletions

View File

@ -0,0 +1,118 @@
# NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT
# NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT
```cpp
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(type, base_type, member...) // (1)
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) // (2)
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(type, base_type, member...) // (3)
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) // (4)
```
These macros can be used to simplify the serialization/deserialization of derived types if you want to use a JSON
object as serialization and want to use the member variable names as object keys in that object.
- Macros 1 and 2 are to be defined **inside** the class/struct to create code for.
Like [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](nlohmann_define_type_intrusive.md), they can access private members.
- Macros 3 and 4 are to be defined **outside** the class/struct to create code for, but **inside** its namespace.
Like [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](nlohmann_define_type_non_intrusive.md),
they **cannot** access private members.
The first parameter is the name of the derived class/struct,
the second parameter is the name of the base class/struct and all remaining parameters name the members.
The base type **must** be already serializable/deserializable.
- Macros 1 and 3 will use [`at`](../basic_json/at.md) during deserialization and will throw
[`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a key is missing in the JSON object.
- Macros 2 and 4 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
default constructs an object and uses its values as the defaults when calling the `value` function.
## Parameters
`type` (in)
: name of the type (class, struct) to serialize/deserialize
`base_type` (in)
: name of the base type (class, struct) `type` is derived from
`member` (in)
: name of the member variable to serialize/deserialize; up to 64 members can be given as comma-separated list
## Default definition
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&);
```
Macros 3 and 4 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&);
```
In both cases they call the `to_json`/`from_json` functions of the base type
before serializing/deserializing the members of the derived type:
```cpp
class A { /* ... */ };
class B : public A { /* ... */ };
void to_json(nlohmann::json& j, const B& b) {
nlohmann::to_json(j, static_cast<const A&>(b));
// ...
}
void from_json(const nlohmann::json& j, B& b) {
nlohmann::from_json(j, static_cast<A&>(b));
// ...
}
```
## Notes
!!! info "Prerequisites"
- Macros 1 and 2 have the same prerequisites of NLOHMANN_DEFINE_TYPE_INTRUSIVE.
- Macros 3 and 3 have the same prerequisites of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE.
- Serialization/deserialization of base types must be defined.
!!! warning "Implementation limits"
- See Implementation limits for NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE.
## Examples
Example of `NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE` usage:
```cpp
class A {
double Aa;
double Ab;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(A, Aa, Ab)
};
class B : public A {
int Ba;
int Bb;
NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(B, A, Ba, Bb)
};
```
## See also
- [NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_intrusive.md)
for similar macros that can be defined _inside_ a non-derived type.
- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_non_intrusive.md)
for a similar macros that can be defined _outside_ a non-derived type.
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview.
## Version history
1. Added in version 3.11.x.

View File

@ -263,7 +263,7 @@ template < typename BasicJsonType, typename ConstructibleArrayType,
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
j.template get<typename ConstructibleArrayType::value_type>(),
void())
void())
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{

View File

@ -419,6 +419,32 @@
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__)) }
/*!
@brief macro
@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE
@since version 3.11.x
*/
#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<const BaseType &>(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<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#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<const BaseType&>(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<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
/*!
@brief macro
@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE
@since version 3.11.x
*/
#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<const BaseType &>(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<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#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<const BaseType &>(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<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
// inspired from https://stackoverflow.com/a/26745591
// allows to call any std function as if (e.g. with begin):
// using std::begin; begin(x);

View File

@ -41,7 +41,6 @@
// SPDX-License-Identifier: MIT
#include <utility>
// #include <nlohmann/detail/abi_macros.hpp>
@ -54,7 +53,6 @@
// SPDX-License-Identifier: MIT
// This file contains all macro definitions affecting or depending on the ABI
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
@ -156,7 +154,6 @@
// SPDX-License-Identifier: MIT
#include <algorithm> // transform
#include <array> // array
#include <forward_list> // forward_list
@ -179,7 +176,6 @@
// SPDX-License-Identifier: MIT
#include <cstddef> // nullptr_t
#include <exception> // exception
#if JSON_DIAGNOSTICS
@ -199,7 +195,6 @@
// SPDX-License-Identifier: MIT
#include <array> // array
#include <cstddef> // size_t
#include <cstdint> // uint8_t
@ -215,7 +210,6 @@
// SPDX-License-Identifier: MIT
#include <utility> // declval, pair
// #include <nlohmann/detail/meta/detected.hpp>
// __ _____ _____ _____
@ -227,7 +221,6 @@
// SPDX-License-Identifier: MIT
#include <type_traits>
// #include <nlohmann/detail/meta/void_t.hpp>
@ -240,7 +233,6 @@
// SPDX-License-Identifier: MIT
// #include <nlohmann/detail/abi_macros.hpp>
@ -2771,6 +2763,33 @@ 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 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__)) }
/*!
@brief macro
@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE
@since version 3.11.x
*/
#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<const BaseType &>(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<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#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<const BaseType&>(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<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
/*!
@brief macro
@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE
@since version 3.11.x
*/
#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<const BaseType &>(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<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#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<const BaseType &>(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<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
// inspired from https://stackoverflow.com/a/26745591
// allows to call any std function as if (e.g. with begin):
// using std::begin; begin(x);
@ -2940,7 +2959,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
// #include <nlohmann/detail/abi_macros.hpp>
@ -3015,7 +3033,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstddef> // size_t
// #include <nlohmann/detail/abi_macros.hpp>
@ -3058,7 +3075,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <array> // array
#include <cstddef> // size_t
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
@ -3231,7 +3247,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <limits> // numeric_limits
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
#include <utility> // declval
@ -3247,7 +3262,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <iterator> // random_access_iterator_tag
// #include <nlohmann/detail/abi_macros.hpp>
@ -3315,7 +3329,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
// #include <nlohmann/detail/macro_scope.hpp>
@ -3335,7 +3348,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
// #include <nlohmann/detail/macro_scope.hpp>
@ -4153,7 +4165,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstring> // strlen
#include <string> // string
#include <utility> // forward
@ -4539,7 +4550,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
// #include <nlohmann/detail/abi_macros.hpp>
@ -4563,7 +4573,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
// #include <nlohmann/detail/macro_scope.hpp>
@ -4826,7 +4835,7 @@ template < typename BasicJsonType, typename ConstructibleArrayType,
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
j.template get<typename ConstructibleArrayType::value_type>(),
void())
void())
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
@ -5069,7 +5078,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <algorithm> // copy
#include <iterator> // begin, end
#include <string> // string
@ -5089,7 +5097,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstddef> // size_t
#include <iterator> // input_iterator_tag
#include <string> // string, to_string
@ -5810,7 +5817,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstdint> // uint8_t, uint64_t
#include <tuple> // tie
#include <utility> // move
@ -5922,7 +5928,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstdint> // uint8_t
#include <cstddef> // size_t
#include <functional> // hash
@ -6055,7 +6060,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <algorithm> // generate_n
#include <array> // array
#include <cmath> // ldexp
@ -6081,7 +6085,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <array> // array
#include <cstddef> // size_t
#include <cstring> // strlen
@ -6576,7 +6579,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstddef>
#include <string> // string
#include <utility> // move
@ -7308,7 +7310,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <array> // array
#include <clocale> // localeconv
#include <cstddef> // size_t
@ -8947,7 +8948,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstdint> // size_t
#include <utility> // declval
#include <string> // string
@ -12099,7 +12099,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cmath> // isfinite
#include <cstdint> // uint8_t
#include <functional> // function
@ -12628,7 +12627,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
// #include <nlohmann/detail/abi_macros.hpp>
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
@ -12641,7 +12639,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstddef> // ptrdiff_t
#include <limits> // numeric_limits
@ -12800,7 +12797,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
#include <type_traits> // conditional, is_const, remove_const
@ -13562,7 +13558,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <cstddef> // ptrdiff_t
#include <iterator> // reverse_iterator
#include <utility> // declval
@ -13731,7 +13726,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <algorithm> // all_of
#include <cctype> // isdigit
#include <cerrno> // errno, ERANGE
@ -14726,7 +14720,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <initializer_list>
#include <utility>
@ -14818,7 +14811,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <algorithm> // reverse
#include <array> // array
#include <map> // map
@ -14844,7 +14836,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <algorithm> // copy
#include <cstddef> // size_t
#include <iterator> // back_inserter
@ -16813,7 +16804,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <algorithm> // reverse, remove, fill, find, none_of
#include <array> // array
#include <clocale> // localeconv, lconv
@ -16838,7 +16828,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <array> // array
#include <cmath> // signbit, isfinite
#include <cstdint> // intN_t, uintN_t
@ -18933,7 +18922,6 @@ NLOHMANN_JSON_NAMESPACE_END
// SPDX-License-Identifier: MIT
#include <functional> // equal_to, less
#include <initializer_list> // initializer_list
#include <iterator> // input_iterator_tag, iterator_traits
@ -24489,7 +24477,6 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC
// SPDX-License-Identifier: MIT
// restore clang diagnostic settings
#if defined(__clang__)
#pragma clang diagnostic pop
@ -24534,7 +24521,6 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC
// SPDX-License-Identifier: MIT
#undef JSON_HEDLEY_ALWAYS_INLINE
#undef JSON_HEDLEY_ARM_VERSION
#undef JSON_HEDLEY_ARM_VERSION_CHECK
@ -24685,5 +24671,4 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC
#undef JSON_HEDLEY_FALL_THROUGH
#endif // INCLUDE_NLOHMANN_JSON_HPP_

View File

@ -25,7 +25,6 @@
// SPDX-License-Identifier: MIT
// This file contains all macro definitions affecting or depending on the ABI
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK

View File

@ -38,6 +38,26 @@ class person_with_private_data
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
};
class derived_person_with_private_data : public person_with_private_data
{
private:
std::string hair_color{"blue"};
public:
bool operator==(const derived_person_with_private_data& rhs) const
{
return person_with_private_data::operator==(rhs) && hair_color == rhs.hair_color;
}
derived_person_with_private_data() = default;
derived_person_with_private_data(std::string name_, int age_, json metadata_, std::string hair_color_)
: person_with_private_data(std::move(name_), age_, std::move(metadata_))
, hair_color(std::move(hair_color_))
{}
NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived_person_with_private_data, person_with_private_data, hair_color)
};
class person_with_private_data_2
{
private:
@ -74,6 +94,31 @@ class person_with_private_data_2
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person_with_private_data_2, age, name, metadata)
};
class derived_person_with_private_data_2 : public person_with_private_data_2
{
private:
std::string hair_color{"blue"};
public:
bool operator==(const derived_person_with_private_data_2& rhs) const
{
return person_with_private_data_2::operator==(rhs) && hair_color == rhs.hair_color;
}
derived_person_with_private_data_2() = default;
derived_person_with_private_data_2(std::string name_, int age_, json metadata_, std::string hair_color_)
: person_with_private_data_2(std::move(name_), age_, std::move(metadata_))
, hair_color(std::move(hair_color_))
{}
std::string getHairColor() const
{
return hair_color;
}
NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(derived_person_with_private_data_2, person_with_private_data_2, hair_color)
};
class person_without_private_data_1
{
public:
@ -96,6 +141,26 @@ class person_without_private_data_1
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_without_private_data_1, age, name, metadata)
};
class derived_person_without_private_data_1 : public person_without_private_data_1
{
public:
std::string hair_color{"blue"};
public:
bool operator==(const derived_person_without_private_data_1& rhs) const
{
return person_without_private_data_1::operator==(rhs) && hair_color == rhs.hair_color;
}
derived_person_without_private_data_1() = default;
derived_person_without_private_data_1(std::string name_, int age_, json metadata_, std::string hair_color_)
: person_without_private_data_1(std::move(name_), age_, std::move(metadata_))
, hair_color(std::move(hair_color_))
{}
NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived_person_without_private_data_1, person_without_private_data_1, hair_color)
};
class person_without_private_data_2
{
public:
@ -118,6 +183,26 @@ class person_without_private_data_2
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)
class derived_person_without_private_data_2 : public person_without_private_data_2
{
public:
std::string hair_color{"blue"};
public:
bool operator==(const derived_person_without_private_data_2& rhs) const
{
return person_without_private_data_2::operator==(rhs) && hair_color == rhs.hair_color;
}
derived_person_without_private_data_2() = default;
derived_person_without_private_data_2(std::string name_, int age_, json metadata_, std::string hair_color_)
: person_without_private_data_2(std::move(name_), age_, std::move(metadata_))
, hair_color(std::move(hair_color_))
{}
};
NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(derived_person_without_private_data_2, person_without_private_data_2, hair_color)
class person_without_private_data_3
{
public:
@ -153,6 +238,31 @@ class person_without_private_data_3
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person_without_private_data_3, age, name, metadata)
class derived_person_without_private_data_3 : public person_without_private_data_3
{
public:
std::string hair_color{"blue"};
public:
bool operator==(const derived_person_without_private_data_3& rhs) const
{
return person_without_private_data_3::operator==(rhs) && hair_color == rhs.hair_color;
}
derived_person_without_private_data_3() = default;
derived_person_without_private_data_3(std::string name_, int age_, json metadata_, std::string hair_color_)
: person_without_private_data_3(std::move(name_), age_, std::move(metadata_))
, hair_color(std::move(hair_color_))
{}
std::string getHairColor() const
{
return hair_color;
}
};
NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(derived_person_without_private_data_3, person_without_private_data_3, hair_color)
class person_with_private_alphabet
{
public:
@ -216,6 +326,19 @@ 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:
@ -279,6 +402,18 @@ 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)
class derived_person_with_public_alphabet : public person_with_public_alphabet
{
public:
bool operator==(const derived_person_with_public_alphabet& other) const
{
return person_with_public_alphabet::operator==(other) && schwa == other.schwa;
}
int schwa = 0;
};
NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(derived_person_with_public_alphabet, person_with_public_alphabet, schwa)
} // namespace persons
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
@ -307,6 +442,32 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU
}
}
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE", T,
persons::derived_person_with_private_data,
persons::derived_person_without_private_data_1,
persons::derived_person_without_private_data_2)
{
SECTION("person")
{
// serialization
T p1("Erik", 1, {{"haircuts", 2}}, "red");
CHECK(json(p1).dump() == "{\"age\":1,\"hair_color\":\"red\",\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}");
// deserialization
auto p2 = json(p1).get<T>();
CHECK(p2 == p1);
// roundtrip
CHECK(T(json(p1)) == p1);
CHECK(json(T(json(p1))) == json(p1));
// check exception in case of missing field
json j = json(p1);
j.erase("age");
CHECK_THROWS_WITH_AS(j.get<T>(), "[json.exception.out_of_range.403] key 'age' not found", 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,
persons::person_with_private_data_2,
persons::person_without_private_data_3)
@ -341,6 +502,42 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU
}
}
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T,
persons::derived_person_with_private_data_2,
persons::derived_person_without_private_data_3)
{
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\":\"\"}");
// serialization
T p1("Erik", 1, {{"haircuts", 2}}, "red");
CHECK(json(p1).dump() == "{\"age\":1,\"hair_color\":\"red\",\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}");
// deserialization
auto p2 = json(p1).get<T>();
CHECK(p2 == p1);
// roundtrip
CHECK(T(json(p1)) == p1);
CHECK(json(T(json(p1))) == json(p1));
// check default value in case of missing field
json j = json(p1);
j.erase("name");
j.erase("age");
j.erase("metadata");
j.erase("hair_color");
T p3 = j.get<T>();
CHECK(p3.getName() == "");
CHECK(p3.getAge() == 0);
CHECK(p3.getMetadata() == nullptr);
CHECK(p3.getHairColor() == "blue");
}
}
TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
persons::person_with_private_alphabet,
persons::person_with_public_alphabet)
@ -412,3 +609,75 @@ TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/priv
}
}
}
TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 27 public/private member variables via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE", T,
persons::derived_person_with_private_alphabet,
persons::derived_person_with_public_alphabet)
{
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<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> 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);
}
}
}