Restructure inline namespace and allow version component to be disabled (#3683)

This commit is contained in:
Florian Albrechtskirchinger 2022-08-10 20:24:16 +02:00 committed by GitHub
parent 93112fbf4d
commit 0e61ee8b07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 500 additions and 99 deletions

View File

@ -183,6 +183,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('Iterators', 'Guide', 'feature
INSERT INTO searchIndex(name, type, path) VALUES ('JSON Merge Patch', 'Guide', 'features/merge_patch/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON Patch and Diff', 'Guide', 'features/json_patch/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON Pointer', 'Guide', 'features/json_pointer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('nlohmann Namespace', 'Guide', 'features/namespace/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Types', 'Guide', 'features/types/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Types: Number Handling', 'Guide', 'features/types/number_handling/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Object Order', 'Guide', 'features/object_order/index.html');
@ -225,6 +226,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTR
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE', 'Macro', 'api/macros/nlohmann_json_namespace/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_BEGIN', 'Macro', 'api/macros/nlohmann_json_namespace_begin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_END', 'Macro', 'api/macros/nlohmann_json_namespace_begin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_NO_VERSION', 'Macro', 'api/macros/nlohmann_json_namespace_no_version/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM', 'Macro', 'api/macros/nlohmann_json_serialize_enum/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MAJOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MINOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');

View File

@ -1 +1 @@
nlohmann::json_v3_11_1
nlohmann::json_abi_v3_11_1

View File

@ -0,0 +1,13 @@
#include <iostream>
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 1
#include <nlohmann/json.hpp>
// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal
#define Q(x) #x
#define QUOTE(x) Q(x)
int main()
{
std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl;
}

View File

@ -0,0 +1 @@
nlohmann::json_abi

View File

@ -32,7 +32,10 @@ header. See also the [macro overview page](../../features/macros.md).
## 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
- [**NLOHMANN_JSON_NAMESPACE_BEGIN**<br>**NLOHMANN_JSON_NAMESPACE_END**](nlohmann_json_namespace_begin.md) - open and
close the library namespace
- [**NLOHMANN_JSON_NAMESPACE_NO_VERSION**](nlohmann_json_namespace_no_version.md) - disable the version component of
the inline namespace
## Type conversions

View File

@ -1,19 +1,18 @@
# NLOHMANN_JSON_NAMESPACE
```cpp
#define NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE /* value */
```
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.
This macro evaluates to the full name of 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)).
The default value consists of the root namespace (`nlohmann`) and an inline ABI namespace. See
[`nlohmann` Namespace](../../features/namespace.md#structure) for details.
When the macro is not defined, the library will define it to its default value.
When the macro is not defined, the library will define it to its default value. Overriding this value has no effect on
the library.
## Examples
@ -35,7 +34,8 @@ 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)
- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](nlohmann_json_namespace_no_version.md)
## Version history
- Added in version 3.11.0.
- Added in version 3.11.0. Changed inline namespace name in version 3.11.2.

View File

@ -1,30 +1,35 @@
# NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END
```cpp
#define NLOHMANN_JSON_NAMESPACE_BEGIN // (1)
#define NLOHMANN_JSON_NAMESPACE_END // (2)
#define NLOHMANN_JSON_NAMESPACE_BEGIN /* value */ // (1)
#define NLOHMANN_JSON_NAMESPACE_END /* value */ // (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.
These macros can be used to open and close the `nlohmann` namespace. See
[`nlohmann` Namespace](../../features/namespace.md#structure) for details.
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.
The default definitions open and close the `nlohmann` namespace. The precise definition of
[`NLOHMANN_JSON_NAMESPACE_BEGIN`] varies as described [here](../../features/namespace.md#structure).
1. Default definition of `NLOHMANN_JSON_NAMESPACE_BEGIN`:
```cpp
namespace nlohmann
{
inline namespace json_abi_v3_11_2
{
```
2. Default definition of `NLOHMANN_JSON_NAMESPACE_END`:
```cpp
} // namespace json_abi_v3_11_2
} // namespace nlohmann
```
When these macros are not defined, the library will define them to their default definitions.
@ -32,7 +37,7 @@ When these macros are not defined, the library will define them to their default
??? example
The example shows an example how to use `NLOHMANN_JSON_NAMESPACE_BEGIN`/`NLOHMANN_JSON_NAMESPACE_END` from the
The example shows how to use `NLOHMANN_JSON_NAMESPACE_BEGIN`/`NLOHMANN_JSON_NAMESPACE_END` from the
[How do I convert third-party types?](../../features/arbitrary_types.md#how-do-i-convert-third-party-types) page.
```cpp
@ -47,8 +52,10 @@ When these macros are not defined, the library will define them to their default
## See also
- [`nlohmann` Namespace](../../features/namespace.md)
- [NLOHMANN_JSON_NAMESPACE](nlohmann_json_namespace.md)
- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](nlohmann_json_namespace_no_version.md)
## Version history
- Added in version 3.11.0.
- Added in version 3.11.0. Changed inline namespace name in version 3.11.2.

View File

@ -0,0 +1,45 @@
# NLOHMANN_JSON_NAMESPACE_NO_VERSION
```cpp
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */
```
If defined to `1`, the version component is omitted from the inline namespace. See
[`nlohmann` Namespace](../../features/namespace.md#structure) for details.
## Default definition
The default value is `0`.
```cpp
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
```
When the macro is not defined, the library will define it to its default value.
## Examples
??? example
The example shows how to use `NLOHMANN_JSON_NAMESPACE_NO_VERSION` to disable the version component of the inline
namespace.
```cpp
--8<-- "examples/nlohmann_json_namespace_no_version.cpp"
```
Output:
```json
--8<-- "examples/nlohmann_json_namespace_no_version.output"
```
## See also
- [`nlohmann` Namespace](../../features/namespace.md)
- [`NLOHMANN_JSON_NAMESPACE`](nlohmann_json_namespace.md)
- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](nlohmann_json_namespace_begin.md)
## Version history
- Added in version 3.11.2.

View File

@ -0,0 +1,93 @@
# `nlohmann` Namespace
The 3.11.0 release introduced an
[inline namespace](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces) to allow different parts of
a codebase to safely use different versions of the JSON library as long as they never exchange instances of library
types.
## Structure
The complete default namespace name is derived as follows:
- The root namespace is always `nlohmann`.
- The inline namespace starts with `json_abi` and is followed by serveral optional ABI tags according to the value of
these ABI-affecting macros, in order:
- [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) defined non-zero appends `_diag`.
- [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md)
defined non-zero appends `_ldvcmp`.
- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by
underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component)
below.
For example, the namespace name for version 3.11.2 with `JSON_DIAGNOSTICS` defined to `1` is:
```cpp
nlohmann::json_abi_diag_v3_11_2
```
## Purpose
Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different
definitions of [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This is illustrated in the diagram below.
```plantuml
[**nlohmann_json (v3.10.5)**\nJSON_DIAGNOSTICS=0] as [json]
[**nlohmann_json (v3.10.5)**\nJSON_DIAGNOSTICS=1] as [json_diag]
[**some_library**] as [library]
[**application**] as [app]
[library] ..|> [json]
[app] ..|> [json_diag]
[app] ..|>[library]
```
In releases prior to 3.11.0, mixing any version of the JSON library with different `JSON_DIAGNOSTICS` settings would
result in a crashing application. If `some_library` never passes instances of JSON library types to the application,
this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names.
## Limitations
Neither the compiler nor the linker will issue as much as a warning when translation units intended to be linked
together and that include different versions and/or configurations of the JSON library exchange and use library
types.
There is an exception when forward declarations are used (i.e., when including `json_fwd.hpp`) in which case the linker
may complain about undefined references.
## Disabling the version component
Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and
recommends that all parts of a codebase exchanging library types be built with the same version. Users can, **at their
own risk**, disable the version component of the linline namespace, allowing different versions but not
configurations to be used in cases where the linker would otherwise output undefined reference errors.
To do so, define [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](../api/macros/nlohmann_json_namespace_no_version.md) to `1`.
This applies to version 3.11.2 and above only, versions 3.11.0 and 3.11.1 can apply the technique described in the next
section to emulate the effect of the `NLOHMANN_JSON_NAMESPACE_NO_VERSION` macro.
!!! danger "Use at your own risk"
Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect
behavior. You have been warned!
## Disabling the inline namespace completely
When interoperability with code using a pre-3.11.0 version of the library is required, users can, **at their own risk**
restore the old namespace layout by redefining
[`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](../api/macros/nlohmann_json_namespace_begin.md) as
follows:
```cpp
#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann {
#define NLOHMANN_JSON_NAMESPACE_END }
```
!!! danger "Use at your own risk"
Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You
have been warned!
## Version history
- Introduced inline namespace (`json_v3_11_0[_abi-tag]*`) in version 3.11.0.
- Changed structure of inline namespace in version 3.11.2.

View File

@ -58,6 +58,7 @@ nav:
- features/json_pointer.md
- features/json_patch.md
- features/merge_patch.md
- 'nlohmann Namespace': features/namespace.md
- features/object_order.md
- Parsing:
- features/parsing/index.md
@ -270,6 +271,7 @@ nav:
- '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_NAMESPACE_NO_VERSION': api/macros/nlohmann_json_namespace_no_version.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

View File

@ -42,38 +42,59 @@
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
#endif
#define NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch) \
json_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_ABI_PREFIX(major, minor, patch) \
NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch)
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
#endif
#define NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c) a ## b ## c
#define NLOHMANN_JSON_ABI_CONCAT(a, b, c) \
NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c)
// Construct the namespace ABI tags component
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
#define NLOHMANN_JSON_ABI_STRING \
NLOHMANN_JSON_ABI_CONCAT( \
NLOHMANN_JSON_ABI_PREFIX( \
NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH), \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
#define NLOHMANN_JSON_ABI_TAGS \
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
// Construct the namespace version component
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_VERSION
#else
#define NLOHMANN_JSON_NAMESPACE_VERSION \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH)
#endif
// Combine namespace components
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
#ifndef NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE nlohmann::NLOHMANN_JSON_ABI_STRING
#define NLOHMANN_JSON_NAMESPACE \
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION)
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_ABI_STRING \
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION) \
{
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (abi_string) */ \
} /* namespace nlohmann */
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
} // namespace nlohmann
#endif

View File

@ -90,40 +90,61 @@
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
#endif
#define NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch) \
json_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_ABI_PREFIX(major, minor, patch) \
NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch)
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
#endif
#define NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c) a ## b ## c
#define NLOHMANN_JSON_ABI_CONCAT(a, b, c) \
NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c)
// Construct the namespace ABI tags component
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
#define NLOHMANN_JSON_ABI_STRING \
NLOHMANN_JSON_ABI_CONCAT( \
NLOHMANN_JSON_ABI_PREFIX( \
NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH), \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
#define NLOHMANN_JSON_ABI_TAGS \
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
// Construct the namespace version component
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_VERSION
#else
#define NLOHMANN_JSON_NAMESPACE_VERSION \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH)
#endif
// Combine namespace components
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
#ifndef NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE nlohmann::NLOHMANN_JSON_ABI_STRING
#define NLOHMANN_JSON_NAMESPACE \
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION)
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_ABI_STRING \
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION) \
{
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (abi_string) */ \
} /* namespace nlohmann */
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
} // namespace nlohmann
#endif
// #include <nlohmann/detail/conversions/from_json.hpp>

View File

@ -60,40 +60,61 @@
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
#endif
#define NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch) \
json_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_ABI_PREFIX(major, minor, patch) \
NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch)
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
#endif
#define NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c) a ## b ## c
#define NLOHMANN_JSON_ABI_CONCAT(a, b, c) \
NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c)
// Construct the namespace ABI tags component
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
#define NLOHMANN_JSON_ABI_STRING \
NLOHMANN_JSON_ABI_CONCAT( \
NLOHMANN_JSON_ABI_PREFIX( \
NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH), \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
#define NLOHMANN_JSON_ABI_TAGS \
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
// Construct the namespace version component
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_VERSION
#else
#define NLOHMANN_JSON_NAMESPACE_VERSION \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH)
#endif
// Combine namespace components
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
#ifndef NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE nlohmann::NLOHMANN_JSON_ABI_STRING
#define NLOHMANN_JSON_NAMESPACE \
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION)
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_ABI_STRING \
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION) \
{
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (abi_string) */ \
} /* namespace nlohmann */
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
} // namespace nlohmann
#endif

View File

@ -25,5 +25,6 @@ add_library(abi_compat_main STATIC main.cpp)
target_link_libraries(abi_compat_main PUBLIC abi_compat_common)
# add individual tests
add_subdirectory(config)
add_subdirectory(diag)
add_subdirectory(inline_ns)

View File

@ -0,0 +1,22 @@
# test the different options to change the namespace
# test default namespace
add_executable(abi_config_default default.cpp)
target_link_libraries(abi_config_default PRIVATE abi_compat_main)
add_test(
NAME test-abi_config_default
COMMAND abi_config_default ${DOCTEST_TEST_FILTER})
# test no version namespace
add_executable(abi_config_noversion noversion.cpp)
target_link_libraries(abi_config_noversion PRIVATE abi_compat_main)
add_test(
NAME test-abi_config_noversion
COMMAND abi_config_noversion ${DOCTEST_TEST_FILTER})
# test custom namespace
add_executable(abi_config_custom custom.cpp)
target_link_libraries(abi_config_custom PRIVATE abi_compat_main)
add_test(
NAME test-abi_config_custom
COMMAND abi_config_custom ${DOCTEST_TEST_FILTER})

View File

@ -0,0 +1,35 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
// | | |__ | | | | | | version 3.11.1
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#pragma once
#include "doctest.h"
#include <iostream>
#include <regex>
#include <string>
#define STRINGIZE_EX(x) #x
#define STRINGIZE(x) STRINGIZE_EX(x)
template<typename T>
std::string namespace_name(std::string ns, T* /*unused*/ = nullptr) // NOLINT(performance-unnecessary-value-param)
{
#if DOCTEST_MSVC && !DOCTEST_CLANG
ns = __FUNCSIG__;
#elif !DOCTEST_CLANG
ns = __PRETTY_FUNCTION__;
#endif
std::smatch m;
// extract the true namespace name from the function signature
CAPTURE(ns);
CHECK(std::regex_search(ns, m, std::regex("nlohmann(::[a-zA-Z0-9_]+)*::basic_json")));
return m.str();
}

View File

@ -0,0 +1,33 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
// | | |__ | | | | | | version 3.11.1
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#include "doctest_compatibility.h"
#include "config.hpp"
// define custom namespace
#define NLOHMANN_JSON_NAMESPACE nlohmann // this line may be omitted
#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann {
#define NLOHMANN_JSON_NAMESPACE_END }
#include <nlohmann/json_fwd.hpp>
TEST_CASE("custom namespace")
{
// GCC 4.8 fails with regex_error
#if !DOCTEST_GCC || DOCTEST_GCC >= DOCTEST_COMPILER(4, 9, 0)
SECTION("namespace matches expectation")
{
std::string expected = "nlohmann::basic_json";
// fallback for Clang
std::string ns{STRINGIZE(NLOHMANN_JSON_NAMESPACE) "::basic_json"};
CHECK(namespace_name<nlohmann::json>(ns) == expected);
}
#endif
}

View File

@ -0,0 +1,41 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
// | | |__ | | | | | | version 3.11.1
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#include "doctest_compatibility.h"
#include "config.hpp"
#include <nlohmann/json_fwd.hpp>
TEST_CASE("default namespace")
{
// GCC 4.8 fails with regex_error
#if !DOCTEST_GCC || DOCTEST_GCC >= DOCTEST_COMPILER(4, 9, 0)
SECTION("namespace matches expectation")
{
std::string expected = "nlohmann::json_abi";
#if JSON_DIAGNOSTICS
expected += "_diag";
#endif
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
expected += "_ldvcmp";
#endif
expected += "_v" STRINGIZE(NLOHMANN_JSON_VERSION_MAJOR);
expected += "_" STRINGIZE(NLOHMANN_JSON_VERSION_MINOR);
expected += "_" STRINGIZE(NLOHMANN_JSON_VERSION_PATCH) "::basic_json";
// fallback for Clang
std::string ns{STRINGIZE(NLOHMANN_JSON_NAMESPACE) "::basic_json"};
CHECK(namespace_name<nlohmann::json>(ns) == expected);
}
#endif
}

View File

@ -0,0 +1,40 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
// | | |__ | | | | | | version 3.11.1
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#include "doctest_compatibility.h"
#include "config.hpp"
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 1
#include <nlohmann/json_fwd.hpp>
TEST_CASE("default namespace without version component")
{
// GCC 4.8 fails with regex_error
#if !DOCTEST_GCC || DOCTEST_GCC >= DOCTEST_COMPILER(4, 9, 0)
SECTION("namespace matches expectation")
{
std::string expected = "nlohmann::json_abi";
#if JSON_DIAGNOSTICS
expected += "_diag";
#endif
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
expected += "_ldvcmp";
#endif
expected += "::basic_json";
// fallback for Clang
std::string ns{STRINGIZE(NLOHMANN_JSON_NAMESPACE) "::basic_json"};
CHECK(namespace_name<nlohmann::json>(ns) == expected);
}
#endif
}

View File

@ -36,8 +36,8 @@ SOFTWARE.
* file doc/README.md. *
\****************************************************************************/
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
#define INCLUDE_NLOHMANN_JSON_HPP_
#ifndef INCLUDE_NLOHMANN_JSON_V3_10_5_HPP_
#define INCLUDE_NLOHMANN_JSON_V3_10_5_HPP_
#define NLOHMANN_JSON_VERSION_MAJOR 3
#define NLOHMANN_JSON_VERSION_MINOR 10
@ -22088,4 +22088,4 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std
#endif // INCLUDE_NLOHMANN_JSON_HPP_
#endif // INCLUDE_NLOHMANN_JSON_V3_10_5_HPP_

View File

@ -1,7 +1,7 @@
import gdb
import re
ns_pattern = re.compile(r'nlohmann::json_v(?P<v_major>\d+)_(?P<v_minor>\d+)_(?P<v_patch>\d+)(?P<tags>\w*)::(?P<name>.+)')
ns_pattern = re.compile(r'nlohmann(::json_abi(?P<tags>\w*)(_v(?P<v_major>\d+)_(?P<v_minor>\d+)_(?P<v_patch>\d+))?)?::(?P<name>.+)')
class JsonValuePrinter:
"Print a json-value"
@ -26,7 +26,7 @@ def json_lookup_function(val):
return gdb.default_visualizer(union_val.dereference())
else:
return JsonValuePrinter(union_val)
except:
except Exception:
return JsonValuePrinter(val['m_type'])
gdb.pretty_printers.append(json_lookup_function)