mirror of
https://github.com/nlohmann/json.git
synced 2025-11-24 11:54:34 +08:00
Add versioned, ABI-tagged inline namespace and namespace macros (#3590)
* Add versioned inline namespace Add a versioned inline namespace to prevent ABI issues when linking code using multiple library versions. * Add namespace macros * Encode ABI information in inline namespace Add _diag suffix to inline namespace if JSON_DIAGNOSTICS is enabled, and _ldvcmp suffix if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON is enabled. * Move ABI-affecting macros into abi_macros.hpp * Move std_fs namespace definition into std_fs.hpp * Remove std_fs namespace from unit test * Format more files in tests directory * Add unit tests * Update documentation * Fix GDB pretty printer * fixup! Add namespace macros * Derive ABI prefix from NLOHMANN_JSON_VERSION_*
This commit is contained in:
committed by
GitHub
parent
fca1ddda96
commit
d909f80960
@@ -27,6 +27,11 @@ header. See also the [macro overview page](../../features/macros.md).
|
||||
- [**JSON_SKIP_LIBRARY_VERSION_CHECK**](json_skip_library_version_check.md) - skip library version check
|
||||
- [**NLOHMANN_JSON_VERSION_MAJOR**<br>**NLOHMANN_JSON_VERSION_MINOR**<br>**NLOHMANN_JSON_VERSION_PATCH**](nlohmann_json_version_major.md) - library version information
|
||||
|
||||
## Library namespace
|
||||
|
||||
- [**NLOHMANN_JSON_NAMESPACE**](nlohmann_json_namespace.md) - full name of the `nlohmann` namespace
|
||||
- [**NLOHMANN_JSON_NAMESPACE_BEGIN**<br>**NLOHMANN_JSON_NAMESPACE_END**](nlohmann_json_namespace_begin.md) - open and close the library namespace
|
||||
|
||||
## Type conversions
|
||||
|
||||
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums
|
||||
|
||||
@@ -26,11 +26,16 @@ When the macro is not defined, the library will define it to its default value.
|
||||
|
||||
## Notes
|
||||
|
||||
!!! danger "ABI incompatibility"
|
||||
!!! note "ABI compatibility"
|
||||
|
||||
As this macro changes the definition of the `basic_json` object, it MUST be defined in the same way globally, even
|
||||
across different compilation units: `basic_json` objects with differently defined `JSON_DIAGNOSTICS` macros are
|
||||
not compatible!
|
||||
As of version 3.11.0, this macro is no longer required to be defined consistently throughout a codebase to avoid
|
||||
One Definition Rule (ODR) violations, as the value of this macro is encoded in the namespace, resulting in distinct
|
||||
symbol names.
|
||||
|
||||
This allows different parts of a codebase to use different versions or configurations of this library without
|
||||
causing improper behavior.
|
||||
|
||||
Where possible, it is still recommended that all code define this the same way for maximum interoperability.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -65,3 +70,4 @@ When the macro is not defined, the library will define it to its default value.
|
||||
## Version history
|
||||
|
||||
- Added in version 3.10.0.
|
||||
- As of version 3.11.0 the definition is allowed to vary between translation units.
|
||||
|
||||
26
docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md
Normal file
26
docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# NLOHMANN_JSON_NAMESPACE
|
||||
|
||||
```cpp
|
||||
#define NLOHMANN_JSON_NAMESPACE
|
||||
```
|
||||
|
||||
This macro evaluates to the full name of the `nlohmann` namespace, including
|
||||
the name of a versioned and ABI-tagged inline namespace. Use this macro to
|
||||
unambiguously refer to the `nlohmann` namespace.
|
||||
|
||||
## Default definition
|
||||
|
||||
The default value consists of a prefix, a version string, and optional ABI tags
|
||||
depending on whether ABI-affecting macros are defined (e.g.,
|
||||
[`JSON_DIAGNOSTICS`](json_diagnostics.md), and
|
||||
[`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](json_use_legacy_discarded_value_comparison.md)).
|
||||
|
||||
When the macro is not defined, the library will define it to its default value.
|
||||
|
||||
## See also
|
||||
|
||||
- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](nlohmann_json_namespace_begin.md)
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.11.0.
|
||||
40
docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md
Normal file
40
docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
```cpp
|
||||
#define NLOHMANN_JSON_NAMESPACE_BEGIN // (1)
|
||||
#define NLOHMANN_JSON_NAMESPACE_END // (2)
|
||||
```
|
||||
|
||||
These macros can be used to open and close the `nlohmann` namespace. They
|
||||
include an inline namespace used to differentiate symbols when linking multiple
|
||||
versions (including different ABI-affecting macros) of this library.
|
||||
|
||||
1. Opens the namespace.
|
||||
```cpp
|
||||
namespace nlohmann
|
||||
{
|
||||
inline namespace json_v3_11_0
|
||||
{
|
||||
```
|
||||
|
||||
2. Closes the namespace.
|
||||
```cpp
|
||||
} // namespace nlohmann
|
||||
} // json_v3_11_0
|
||||
```
|
||||
|
||||
## Default definition
|
||||
|
||||
The default definitions open and close the `nlohmann` as well as an inline
|
||||
namespace.
|
||||
|
||||
When these macros are not defined, the library will define them to their
|
||||
default definitions.
|
||||
|
||||
## See also
|
||||
|
||||
- [NLOHMANN_JSON_NAMESPACE](nlohmann_json_namespace.md)
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.11.0.
|
||||
@@ -155,30 +155,35 @@ To solve this, you need to add a specialization of `adl_serializer` to the `nloh
|
||||
|
||||
```cpp
|
||||
// partial specialization (full specialization works too)
|
||||
namespace nlohmann {
|
||||
template <typename T>
|
||||
struct adl_serializer<boost::optional<T>> {
|
||||
static void to_json(json& j, const boost::optional<T>& opt) {
|
||||
if (opt == boost::none) {
|
||||
j = nullptr;
|
||||
} else {
|
||||
j = *opt; // this will call adl_serializer<T>::to_json which will
|
||||
// find the free function to_json in T's namespace!
|
||||
}
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
template <typename T>
|
||||
struct adl_serializer<boost::optional<T>> {
|
||||
static void to_json(json& j, const boost::optional<T>& opt) {
|
||||
if (opt == boost::none) {
|
||||
j = nullptr;
|
||||
} else {
|
||||
j = *opt; // this will call adl_serializer<T>::to_json which will
|
||||
// find the free function to_json in T's namespace!
|
||||
}
|
||||
}
|
||||
|
||||
static void from_json(const json& j, boost::optional<T>& opt) {
|
||||
if (j.is_null()) {
|
||||
opt = boost::none;
|
||||
} else {
|
||||
opt = j.get<T>(); // same as above, but with
|
||||
// adl_serializer<T>::from_json
|
||||
}
|
||||
static void from_json(const json& j, boost::optional<T>& opt) {
|
||||
if (j.is_null()) {
|
||||
opt = boost::none;
|
||||
} else {
|
||||
opt = j.get<T>(); // same as above, but with
|
||||
// adl_serializer<T>::from_json
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
```
|
||||
|
||||
!!! note "ABI compatibility"
|
||||
|
||||
Use [`NLOHMANN_JSON_NAMESPACE_BEGIN`](../api/macros/nlohmann_json_namespace_begin.md) and `NLOHMANN_JSON_NAMESPACE_END`
|
||||
instead of `#!cpp namespace nlohmann { }` in code which may be linked with different versions of this library.
|
||||
|
||||
## How can I use `get()` for non-default constructible/non-copyable types?
|
||||
|
||||
There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:
|
||||
|
||||
@@ -264,6 +264,9 @@ nav:
|
||||
- 'NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT': api/macros/nlohmann_define_type_intrusive.md
|
||||
- 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE': api/macros/nlohmann_define_type_non_intrusive.md
|
||||
- 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT': api/macros/nlohmann_define_type_non_intrusive.md
|
||||
- 'NLOHMANN_JSON_NAMESPACE': api/macros/nlohmann_json_namespace.md
|
||||
- 'NLOHMANN_JSON_NAMESPACE_BEGIN': api/macros/nlohmann_json_namespace_begin.md
|
||||
- 'NLOHMANN_JSON_NAMESPACE_END': api/macros/nlohmann_json_namespace_begin.md
|
||||
- 'NLOHMANN_JSON_SERIALIZE_ENUM': api/macros/nlohmann_json_serialize_enum.md
|
||||
- 'NLOHMANN_JSON_VERSION_MAJOR': api/macros/nlohmann_json_version_major.md
|
||||
- 'NLOHMANN_JSON_VERSION_MINOR': api/macros/nlohmann_json_version_major.md
|
||||
|
||||
Reference in New Issue
Block a user