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