diff --git a/docs/mkdocs/docs/api/macros/index.md b/docs/mkdocs/docs/api/macros/index.md index d95869b93..06a65cb4d 100644 --- a/docs/mkdocs/docs/api/macros/index.md +++ b/docs/mkdocs/docs/api/macros/index.md @@ -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**
**NLOHMANN_JSON_VERSION_MINOR**
**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**
**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 diff --git a/docs/mkdocs/docs/api/macros/json_diagnostics.md b/docs/mkdocs/docs/api/macros/json_diagnostics.md index d42025092..c6a4dac3f 100644 --- a/docs/mkdocs/docs/api/macros/json_diagnostics.md +++ b/docs/mkdocs/docs/api/macros/json_diagnostics.md @@ -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. diff --git a/docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md b/docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md new file mode 100644 index 000000000..d76bffb81 --- /dev/null +++ b/docs/mkdocs/docs/api/macros/nlohmann_json_namespace.md @@ -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. diff --git a/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md b/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md new file mode 100644 index 000000000..83844b502 --- /dev/null +++ b/docs/mkdocs/docs/api/macros/nlohmann_json_namespace_begin.md @@ -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. diff --git a/docs/mkdocs/docs/features/arbitrary_types.md b/docs/mkdocs/docs/features/arbitrary_types.md index 49a541ef5..a539ad815 100644 --- a/docs/mkdocs/docs/features/arbitrary_types.md +++ b/docs/mkdocs/docs/features/arbitrary_types.md @@ -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 - struct adl_serializer> { - static void to_json(json& j, const boost::optional& opt) { - if (opt == boost::none) { - j = nullptr; - } else { - j = *opt; // this will call adl_serializer::to_json which will - // find the free function to_json in T's namespace! - } +NLOHMANN_JSON_NAMESPACE_BEGIN +template +struct adl_serializer> { + static void to_json(json& j, const boost::optional& opt) { + if (opt == boost::none) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer::to_json which will + // find the free function to_json in T's namespace! } + } - static void from_json(const json& j, boost::optional& opt) { - if (j.is_null()) { - opt = boost::none; - } else { - opt = j.get(); // same as above, but with - // adl_serializer::from_json - } + static void from_json(const json& j, boost::optional& opt) { + if (j.is_null()) { + opt = boost::none; + } else { + opt = j.get(); // same as above, but with + // adl_serializer::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: diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index 8b7dc4762..6d2889c84 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -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