mirror of
https://github.com/nlohmann/json.git
synced 2026-10-25 15:28:54 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64a5d233d0 | ||
|
|
315bd04c55 | ||
|
|
ea3dca202b |
No files matched your search
@@ -163,9 +163,9 @@ jobs:
|
|||||||
python3 $GENERATOR --list-tags
|
python3 $GENERATOR --list-tags
|
||||||
TAG_COUNT=$(python3 $GENERATOR --list-tags | wc -l)
|
TAG_COUNT=$(python3 $GENERATOR --list-tags | wc -l)
|
||||||
|
|
||||||
python3 $GENERATOR --abi-tags diag,_dp,_vns --abi-tags _diag --output $RUNNER_TEMP/abi_tags.natvis
|
python3 $GENERATOR --abi-tags diag,_dp,_ns --abi-tags _diag --output $RUNNER_TEMP/abi_tags.natvis
|
||||||
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_vns -->' $RUNNER_TEMP/abi_tags.natvis
|
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_ns -->' $RUNNER_TEMP/abi_tags.natvis
|
||||||
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_vns_v[0-9_]* -->' $RUNNER_TEMP/abi_tags.natvis
|
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_ns_v[0-9_]* -->' $RUNNER_TEMP/abi_tags.natvis
|
||||||
test $(grep -c '<!-- Namespace ' $RUNNER_TEMP/abi_tags.natvis) -eq $(( $(grep -c '<!-- Namespace ' nlohmann_json.natvis) + 2 ))
|
test $(grep -c '<!-- Namespace ' $RUNNER_TEMP/abi_tags.natvis) -eq $(( $(grep -c '<!-- Namespace ' nlohmann_json.natvis) + 2 ))
|
||||||
|
|
||||||
python3 $GENERATOR --all --output $RUNNER_TEMP/all.natvis
|
python3 $GENERATOR --all --output $RUNNER_TEMP/all.natvis
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ The "Check amalgamation" workflow fails if the file is out of date.
|
|||||||
|
|
||||||
The file covers the namespace variants with up to two ABI tags. A Natvis file for other configurations can be
|
The file covers the namespace variants with up to two ABI tags. A Natvis file for other configurations can be
|
||||||
generated with the `--abi-tags` or `--all` options, for example
|
generated with the `--abi-tags` or `--all` options, for example
|
||||||
`make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my_nlohmann_json.natvis"`; see
|
`make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_ns --output my_nlohmann_json.natvis"`; see
|
||||||
[`tools/generate_natvis`](tools/generate_natvis/README.md). With MSVC, CMake adds the file to the `nlohmann_json`
|
[`tools/generate_natvis`](tools/generate_natvis/README.md). With MSVC, CMake adds the file to the `nlohmann_json`
|
||||||
target and installs it.
|
target and installs it.
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ $(AMALGAMATED_VIEW_FILE): $(SRCS)
|
|||||||
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_view.json -s . --verbose=yes
|
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_view.json -s . --verbose=yes
|
||||||
|
|
||||||
NATVIS_VENV=tools/generate_natvis/venv
|
NATVIS_VENV=tools/generate_natvis/venv
|
||||||
# extra options for generate_natvis.py, e.g. NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my.natvis"
|
# extra options for generate_natvis.py, e.g. NATVIS_ARGS="--abi-tags _diag,_dp,_ns --output my.natvis"
|
||||||
NATVIS_ARGS=
|
NATVIS_ARGS=
|
||||||
|
|
||||||
# regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp
|
# regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp
|
||||||
|
|||||||
@@ -55,10 +55,7 @@ validate with overload 2 first, if the original vector must survive a failed loa
|
|||||||
|
|
||||||
## Exceptions
|
## Exceptions
|
||||||
|
|
||||||
On a big-endian target, throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) -- the same
|
Throws [`parse_error.116`](../../home/exceptions.md#jsonexceptionparse_error116) if `image` is not one
|
||||||
exception [`save()`](save.md#exceptions) throws there, since the image format is little-endian only.
|
|
||||||
|
|
||||||
Otherwise throws [`parse_error.116`](../../home/exceptions.md#jsonexceptionparse_error116) if `image` is not one
|
|
||||||
`save()` could have written, or fails the requested `check`:
|
`save()` could have written, or fails the requested `check`:
|
||||||
|
|
||||||
| message | when |
|
| message | when |
|
||||||
@@ -95,6 +92,9 @@ are checked once, however many nodes refer to it.
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
**Little-endian targets only.** On a big-endian target, `load()` does not exist, just like
|
||||||
|
[`save()`](save.md#notes): the image format is little-endian, so a call fails to compile.
|
||||||
|
|
||||||
### `image_check` { #image_check }
|
### `image_check` { #image_check }
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ Throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) i
|
|||||||
[discarded](is_discarded.md) -- a default-constructed document, or one a failed [`parse()`](parse.md)/
|
[discarded](is_discarded.md) -- a default-constructed document, or one a failed [`parse()`](parse.md)/
|
||||||
[`read()`](read.md) with `allow_exceptions == false` left discarded.
|
[`read()`](read.md) with `allow_exceptions == false` left discarded.
|
||||||
|
|
||||||
On a big-endian target, throws `type_error.320` with a different message instead: the image format is little-endian
|
|
||||||
only (see [Notes](#notes)).
|
|
||||||
|
|
||||||
Throws [`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the node count, the text, or
|
Throws [`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the node count, the text, or
|
||||||
the decoded strings of the image would individually reach 4 GiB -- the same 32-bit offsets
|
the decoded strings of the image would individually reach 4 GiB -- the same 32-bit offsets
|
||||||
[`parse()`](parse.md#exceptions) and, for edits, [`set`](set.md)/[`push_back`](push_back.md) are already limited to.
|
[`parse()`](parse.md#exceptions) and, for edits, [`set`](set.md)/[`push_back`](push_back.md) are already limited to.
|
||||||
@@ -44,9 +41,6 @@ the decoded strings of the image would individually reach 4 GiB -- the same 32-b
|
|||||||
[json.exception.type_error.320] cannot save a discarded json_document
|
[json.exception.type_error.320] cannot save a discarded json_document
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
[json.exception.type_error.320] json_document images need a little-endian target
|
|
||||||
```
|
|
||||||
```
|
|
||||||
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document
|
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -70,9 +64,9 @@ else -- see [`load`'s Exceptions](load.md#exceptions).
|
|||||||
the *same* build on the *same* (little-endian) machine -- not as a long-term storage format. Keep the original
|
the *same* build on the *same* (little-endian) machine -- not as a long-term storage format. Keep the original
|
||||||
JSON text if you need to read a saved document back with a future library version.
|
JSON text if you need to read a saved document back with a future library version.
|
||||||
|
|
||||||
**Little-endian only.** The image is written as raw little-endian bytes, with no byte-swapping. `save()` (and
|
**Little-endian targets only.** The image is written as raw little-endian bytes, with no byte-swapping. On a
|
||||||
[`load`](load.md)) throw `type_error.320` on a big-endian target rather than silently produce bytes a big-endian
|
big-endian target, `save()` and [`load`](load.md) do not exist: a call fails to compile rather than produce bytes a
|
||||||
reader could not interpret correctly.
|
big-endian reader could not interpret correctly.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,25 @@ For the types below, the conversion works directly on the flat index -- no `Basi
|
|||||||
[`materialize()`](materialize.md)) does; `#!cpp std::map<std::string, basic_json_view>` keeps views of the members
|
[`materialize()`](materialize.md)) does; `#!cpp std::map<std::string, basic_json_view>` keeps views of the members
|
||||||
instead of values
|
instead of values
|
||||||
|
|
||||||
Every other `T` -- `#!cpp std::list`, `#!cpp std::pair`, `#!cpp std::array`, enumerations, user types with a
|
A default-constructible `T` whose `from_json()` accepts views reads the view directly as well, member by member, without
|
||||||
`from_json()`, ... -- is converted by `#!cpp materialize().get<T>()`: the subtree is built into a real `BasicJsonType`
|
building a `BasicJsonType` value. This covers the types of the
|
||||||
|
[`NLOHMANN_DEFINE_TYPE_*`](../macros/nlohmann_define_type_intrusive.md) and
|
||||||
|
[`NLOHMANN_DEFINE_DERIVED_TYPE_*`](../macros/nlohmann_define_derived_type.md) macros and the enumerations of
|
||||||
|
[`NLOHMANN_JSON_SERIALIZE_ENUM`](../macros/nlohmann_json_serialize_enum.md), and any `from_json()` constrained to
|
||||||
|
accept views, e.g. with [`is_json_view`](../is_json_view.md). A `from_json()` that also accepts types that are no JSON
|
||||||
|
values at all, such as the unconstrained `#!cpp template<typename BasicJsonType> void from_json(const BasicJsonType&,
|
||||||
|
T&)` of [arbitrary type conversions](../../features/arbitrary_types.md), is not called with a view: it may use
|
||||||
|
`BasicJsonType` functions a view does not have. See [json_view](../../features/json_view.md).
|
||||||
|
|
||||||
|
!!! warning "Duplicate keys"
|
||||||
|
|
||||||
|
Such a `from_json()` looks members up in the view, where a repeated key finds the **first** member, while
|
||||||
|
`#!cpp materialize().get<T>()` sees the **last** one, as [`BasicJsonType::parse()`](../basic_json/parse.md)
|
||||||
|
keeps it: for `#!cpp {"x":1,"x":2}`, `#!cpp get<point>()` reads `#!cpp x == 1`. See
|
||||||
|
[Duplicate keys](../../features/json_view.md#duplicate-keys).
|
||||||
|
|
||||||
|
Every other `T` -- `#!cpp std::list`, `#!cpp std::pair`, `#!cpp std::array`, user types whose `from_json()` is
|
||||||
|
written for `BasicJsonType` only, ... -- is converted by `#!cpp materialize().get<T>()`: the subtree is built into a real `BasicJsonType`
|
||||||
value first (as [`BasicJsonType::parse()`](../basic_json/parse.md) would), and converted from there exactly as
|
value first (as [`BasicJsonType::parse()`](../basic_json/parse.md) would), and converted from there exactly as
|
||||||
[`BasicJsonType::get<T>()`](../basic_json/get.md) would convert it.
|
[`BasicJsonType::get<T>()`](../basic_json/get.md) would convert it.
|
||||||
|
|
||||||
@@ -55,10 +72,13 @@ Strong guarantee: there are no changes to the view or the document it refers to.
|
|||||||
an element to `U` throws.
|
an element to `U` throws.
|
||||||
- For `#!cpp std::map`/`#!cpp std::unordered_map`: throws `type_error.302` if the value is not an object; otherwise,
|
- For `#!cpp std::map`/`#!cpp std::unordered_map`: throws `type_error.302` if the value is not an object; otherwise,
|
||||||
whatever converting a member to the mapped type throws.
|
whatever converting a member to the mapped type throws.
|
||||||
|
- For a `T` whose `from_json()` reads the view: whatever that `from_json()` throws; for the macros, the same
|
||||||
|
exceptions with the same messages as [`BasicJsonType::get<T>()`](../basic_json/get.md) of the same value.
|
||||||
- For every other `T`: whatever [`materialize().get<T>()`](../basic_json/get.md) throws -- typically `type_error.302`,
|
- For every other `T`: whatever [`materialize().get<T>()`](../basic_json/get.md) throws -- typically `type_error.302`,
|
||||||
or whatever a user-provided `from_json()` throws.
|
or whatever a user-provided `from_json()` throws.
|
||||||
|
|
||||||
None of the exceptions thrown directly by this function (the first three bullets above) carry a
|
None of the exceptions thrown directly by this function or by a `from_json()` that reads the view (the first four
|
||||||
|
bullets above) carry a
|
||||||
[`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no `BasicJsonType` value to point at. An
|
[`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no `BasicJsonType` value to point at. An
|
||||||
exception thrown while converting through `materialize()` (the last bullet) is different: it is thrown by a real
|
exception thrown while converting through `materialize()` (the last bullet) is different: it is thrown by a real
|
||||||
`BasicJsonType` value, so it **does** carry a `JSON_DIAGNOSTICS` path if `BasicJsonType` was built with it enabled.
|
`BasicJsonType` value, so it **does** carry a `JSON_DIAGNOSTICS` path if `BasicJsonType` was built with it enabled.
|
||||||
@@ -76,6 +96,8 @@ document.
|
|||||||
- `#!cpp std::map`/`#!cpp std::unordered_map`: linear in the number of members for walking them, plus the container's
|
- `#!cpp std::map`/`#!cpp std::unordered_map`: linear in the number of members for walking them, plus the container's
|
||||||
own insertion cost per member (logarithmic for `#!cpp std::map`, amortized constant for `#!cpp
|
own insertion cost per member (logarithmic for `#!cpp std::map`, amortized constant for `#!cpp
|
||||||
std::unordered_map`), times the complexity of converting one member to the mapped type.
|
std::unordered_map`), times the complexity of converting one member to the mapped type.
|
||||||
|
- a `T` whose `from_json()` reads the view: the cost of that `from_json()`; for the macros, linear in the number of
|
||||||
|
members times the cost of a lookup, plus the cost of converting the members.
|
||||||
- every other `T`: the cost of [`materialize()`](materialize.md) and of destroying the `BasicJsonType` value
|
- every other `T`: the cost of [`materialize()`](materialize.md) and of destroying the `BasicJsonType` value
|
||||||
afterwards, plus that of [`BasicJsonType::get<T>()`](../basic_json/get.md).
|
afterwards, plus that of [`BasicJsonType::get<T>()`](../basic_json/get.md).
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ template<typename T>
|
|||||||
T& get_to(T& v) const;
|
T& get_to(T& v) const;
|
||||||
```
|
```
|
||||||
|
|
||||||
Converts the value to `T` and stores it in `v`, in one of two ways:
|
Converts the value to `T` and stores it in `v`, in one of three ways:
|
||||||
|
|
||||||
- For the types that [`get<T>()`](get.md) converts directly -- arithmetic types, `#!cpp bool`,
|
- For the types that [`get<T>()`](get.md) converts directly -- arithmetic types, `#!cpp bool`,
|
||||||
`#!cpp std::nullptr_t`, [`string_view_t`](index.md#member-types), `#!cpp std::basic_string`, `BasicJsonType`,
|
`#!cpp std::nullptr_t`, [`string_view_t`](index.md#member-types), `#!cpp std::basic_string`, `BasicJsonType`,
|
||||||
`basic_json_view`, `#!cpp std::vector`, and `#!cpp std::map`/`#!cpp std::unordered_map` with string keys -- `v` is
|
`basic_json_view`, `#!cpp std::vector`, and `#!cpp std::map`/`#!cpp std::unordered_map` with string keys -- `v` is
|
||||||
assigned: `#!cpp v = get<T>()`.
|
assigned: `#!cpp v = get<T>()`.
|
||||||
|
- For a type whose `from_json()` accepts views (see [`get<T>()`](get.md)), that `from_json()` is called with the
|
||||||
|
view and the existing `v`, without building a `BasicJsonType` value.
|
||||||
- For every other type, the subtree is built into a `BasicJsonType` value and `#!cpp materialize().get_to(v)` is
|
- For every other type, the subtree is built into a `BasicJsonType` value and `#!cpp materialize().get_to(v)` is
|
||||||
called, i.e. `from_json()` is invoked with the existing `v`, exactly as
|
called, i.e. `from_json()` is invoked with the existing `v`, exactly as
|
||||||
[`BasicJsonType::get_to()`](../basic_json/get_to.md) does.
|
[`BasicJsonType::get_to()`](../basic_json/get_to.md) does.
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ still refers to it -- including ones taken before the change -- reads the new va
|
|||||||
|
|
||||||
## Member types
|
## Member types
|
||||||
|
|
||||||
|
- **basic_json_type** - `BasicJsonType` (it also marks the class for [`is_json_view`](../is_json_view.md))
|
||||||
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
|
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
|
||||||
- **string_t**, **number_integer_t**, **number_unsigned_t**, **number_float_t**, **json_pointer** - the corresponding
|
- **string_t**, **number_integer_t**, **number_unsigned_t**, **number_float_t**, **json_pointer** - the corresponding
|
||||||
member types of `BasicJsonType`
|
member types of `BasicJsonType`
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# <small>nlohmann::</small>is_json_view
|
||||||
|
|
||||||
|
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<typename T>
|
||||||
|
struct is_json_view;
|
||||||
|
```
|
||||||
|
|
||||||
|
A type trait: `#!cpp is_json_view<T>::value` is `#!cpp true` if `T` is a [`basic_json_view`](basic_json_view/index.md)
|
||||||
|
of any `BasicJsonType` and any [`view_mode`](view_mode.md) -- [`json_view`](json_view.md),
|
||||||
|
[`json_editable_view`](json_editable_view.md), [`ordered_json_view`](ordered_json_view.md), ... -- and
|
||||||
|
`#!cpp false` otherwise, for [`basic_json`](basic_json/index.md) as well.
|
||||||
|
|
||||||
|
It is meant for constraining templates that accept views, in particular a `from_json()` that should read views
|
||||||
|
directly: [`get<T>()`](basic_json_view/get.md) on a view calls a `from_json()` with the view only if that `from_json()`
|
||||||
|
accepts views but not arbitrary types.
|
||||||
|
|
||||||
|
## Template parameters
|
||||||
|
|
||||||
|
`T`
|
||||||
|
: the type to check (without cv-qualifiers or references)
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A view is recognized by its member type `basic_json_type` (a [`basic_json`](basic_json/index.md) specialization) and
|
||||||
|
its [`materialize()`](basic_json_view/materialize.md) returning that type, so the trait needs no declaration of the
|
||||||
|
view class.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below shows the trait, and a `from_json()` constrained to `json` values and views: `get<T>()` on a view
|
||||||
|
reads the view directly.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/is_json_view.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
--8<-- "examples/is_json_view.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [basic_json_view](basic_json_view/index.md) - a handle to one value of a document
|
||||||
|
- [get](basic_json_view/get.md) - which conversions read the view directly
|
||||||
|
- [view_mode](view_mode.md) - read-only or editable
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
Added in version 3.13.0.
|
||||||
@@ -43,8 +43,6 @@ header. See also the [macro overview page](../../features/macros.md).
|
|||||||
- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers
|
- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers
|
||||||
- [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace
|
- [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace
|
||||||
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
|
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
|
||||||
- [**JSON_VIEW_NO_SIMD**](json_view_no_simd.md) - use only portable code in the parser of `json_view.hpp`
|
|
||||||
- [**JSON_VIEW_USE_SSSE3**](json_view_use_ssse3.md) - validate non-ASCII strings with SSSE3 in the parser of `json_view.hpp`
|
|
||||||
|
|
||||||
## Library version
|
## Library version
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
When defined, the library uses only portable C++ code where it would otherwise use vector instructions: when scanning
|
When defined, the library uses only portable C++ code where it would otherwise use vector instructions: when scanning
|
||||||
strings during parsing, and when writing floating-point numbers during serialization.
|
strings during parsing, and when writing floating-point numbers during serialization. This includes the parser of
|
||||||
|
[`basic_json_document`](../basic_json_document/index.md) (`<nlohmann/json_view.hpp>`).
|
||||||
|
|
||||||
The macro is an escape hatch, for example for toolchains that cannot compile the vector code, for sanitizers or
|
The macro is an escape hatch, for example for toolchains that cannot compile the vector code, for sanitizers or
|
||||||
analyzers that do not understand it, or to compare the speed of both variants. It does not change any result: values,
|
analyzers that do not understand it, or to compare the speed of both variants. It does not change any result: values,
|
||||||
@@ -77,6 +78,7 @@ By default, `#!cpp JSON_NO_SIMD` is not defined, and vector instructions are use
|
|||||||
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
|
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
|
||||||
- [**JSON_DISABLE_STREAM_BULK_SCAN**](json_disable_stream_bulk_scan.md) - read a `std::istream` one character at a time
|
- [**JSON_DISABLE_STREAM_BULK_SCAN**](json_disable_stream_bulk_scan.md) - read a `std::istream` one character at a time
|
||||||
- [Parsing: input sources and performance](../../features/parsing/index.md#input-sources-and-performance)
|
- [Parsing: input sources and performance](../../features/parsing/index.md#input-sources-and-performance)
|
||||||
|
- [json_view](../../features/json_view.md) - the zero-copy view, whose parser the macro also affects
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
# JSON_VIEW_NO_SIMD
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_VIEW_NO_SIMD
|
|
||||||
```
|
|
||||||
|
|
||||||
When defined, the parser of [`basic_json_document`](../basic_json_document/index.md) (`<nlohmann/json_view.hpp>`)
|
|
||||||
uses only portable C++ to scan strings. By default, it scans long runs of string bytes 16 at a time with NEON on
|
|
||||||
AArch64 (with GCC and Clang) and SSE2 on x86-64, which are part of the baseline instruction sets of these
|
|
||||||
architectures, and validates non-ASCII text with NEON (or SSSE3, see
|
|
||||||
[`JSON_VIEW_USE_SSSE3`](json_view_use_ssse3.md)).
|
|
||||||
|
|
||||||
The same input is accepted or rejected either way, with the same values, and errors are reported the same way; only
|
|
||||||
the speed differs. The macro exists for platforms whose compilers lack the intrinsics headers, and to test the portable
|
|
||||||
code.
|
|
||||||
|
|
||||||
!!! note "ABI compatibility"
|
|
||||||
|
|
||||||
The macro selects between two definitions of the same inline functions. Whether it is defined is encoded in the
|
|
||||||
[namespace](../../features/namespace.md) (tag `_vns`), resulting in distinct symbol names. Translation units
|
|
||||||
compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR)
|
|
||||||
violations, but they cannot exchange instances of library types.
|
|
||||||
|
|
||||||
## Default definition
|
|
||||||
|
|
||||||
By default, `#!cpp JSON_VIEW_NO_SIMD` is not defined, and the vector code is used where available.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#undef JSON_VIEW_NO_SIMD
|
|
||||||
```
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
??? example
|
|
||||||
|
|
||||||
The code below uses the portable string scanning of the view.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_VIEW_NO_SIMD
|
|
||||||
#include <nlohmann/json_view.hpp>
|
|
||||||
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
## See also
|
|
||||||
|
|
||||||
- [JSON_VIEW_USE_SSSE3](json_view_use_ssse3.md) - validate non-ASCII strings with SSSE3 on x86-64
|
|
||||||
- [json_view](../../features/json_view.md) - the zero-copy view
|
|
||||||
|
|
||||||
## Version history
|
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# JSON_VIEW_USE_SSSE3
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define JSON_VIEW_USE_SSSE3
|
|
||||||
```
|
|
||||||
|
|
||||||
When defined on x86-64, the parser of [`basic_json_document`](../basic_json_document/index.md)
|
|
||||||
(`<nlohmann/json_view.hpp>`) validates non-ASCII text in strings with SSSE3 without asking the CPU first.
|
|
||||||
|
|
||||||
By default, the parser checks once at run time whether the CPU has SSSE3 (all x86-64 CPUs since about 2011 have it)
|
|
||||||
and then validates non-ASCII text 16 bytes at a time, using the "lookup4" algorithm of
|
|
||||||
[simdjson](https://github.com/simdjson/simdjson); on CPUs without SSSE3, it validates one UTF-8 sequence at a time.
|
|
||||||
The vector check is compiled for SSSE3 with a function attribute (GCC 4.9 and later, Clang), so this needs no compiler
|
|
||||||
option. With MSVC, the check uses `__cpuid`. On AArch64, the vector check uses NEON and is always on.
|
|
||||||
|
|
||||||
Define the macro only together with a compiler option that enables SSSE3 (e.g. `-mssse3`, or `-march=` with a CPU that
|
|
||||||
has it), and only for programs that run on such CPUs. It saves the check of the CPU, which costs little. The same
|
|
||||||
input is accepted or rejected either way; only the speed of non-ASCII text differs.
|
|
||||||
|
|
||||||
!!! note "ABI compatibility"
|
|
||||||
|
|
||||||
The macro selects between two definitions of the same inline functions. Whether it is defined is encoded in the
|
|
||||||
[namespace](../../features/namespace.md) (tag `_vssse3`, on every architecture), resulting in distinct symbol
|
|
||||||
names. Translation units compiled with and without it can therefore be linked into the same program without One
|
|
||||||
Definition Rule (ODR) violations, but they cannot exchange instances of library types.
|
|
||||||
|
|
||||||
## Default definition
|
|
||||||
|
|
||||||
By default, `#!cpp JSON_VIEW_USE_SSSE3` is not defined.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#undef JSON_VIEW_USE_SSSE3
|
|
||||||
```
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
??? example
|
|
||||||
|
|
||||||
With CMake, for a program that only runs on CPUs with SSSE3:
|
|
||||||
|
|
||||||
```cmake
|
|
||||||
target_compile_definitions(your_target PRIVATE JSON_VIEW_USE_SSSE3)
|
|
||||||
target_compile_options(your_target PRIVATE -mssse3)
|
|
||||||
```
|
|
||||||
|
|
||||||
## See also
|
|
||||||
|
|
||||||
- [JSON_VIEW_NO_SIMD](json_view_no_simd.md) - use only portable code in the view's parser
|
|
||||||
- [JSON_USE_SIMDUTF](json_use_simdutf.md) - validate UTF-8 with simdutf in `basic_json`'s parser
|
|
||||||
|
|
||||||
## Version history
|
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
|
||||||
@@ -147,6 +147,13 @@ void to_json(BasicJsonType& j, const B& b) {
|
|||||||
See Implementation limits for [NLOHMANN_DEFINE_TYPE_INTRUSIVE](nlohmann_define_type_intrusive.md) and
|
See Implementation limits for [NLOHMANN_DEFINE_TYPE_INTRUSIVE](nlohmann_define_type_intrusive.md) and
|
||||||
[NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE](nlohmann_define_type_non_intrusive.md), respectively.
|
[NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE](nlohmann_define_type_non_intrusive.md), respectively.
|
||||||
|
|
||||||
|
!!! info "Views"
|
||||||
|
|
||||||
|
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
|
||||||
|
(`<nlohmann/json_view.hpp>`): [`get<T>()`](../basic_json_view/get.md) on a view looks the members up in the
|
||||||
|
view, without building a `json` value first. The base part is read from the view as well if the base's
|
||||||
|
`from_json()` accepts views, and from [`materialize()`](../basic_json_view/materialize.md) otherwise.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: (1) NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE"
|
??? example "Example: (1) NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE"
|
||||||
@@ -192,3 +199,5 @@ void to_json(BasicJsonType& j, const B& b) {
|
|||||||
6. Added in version 3.12.0.
|
6. Added in version 3.12.0.
|
||||||
|
|
||||||
All six macros were changed to allow an empty member list in version 3.13.0.
|
All six macros were changed to allow an empty member list in version 3.13.0.
|
||||||
|
|
||||||
|
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
|
||||||
@@ -81,6 +81,12 @@ See the examples below for the concrete generated code.
|
|||||||
that serializes a struct's members positionally into a JSON array; for that, write `to_json`/`from_json` by
|
that serializes a struct's members positionally into a JSON array; for that, write `to_json`/`from_json` by
|
||||||
hand, building/reading a `json::array()` of the members in order.
|
hand, building/reading a `json::array()` of the members in order.
|
||||||
|
|
||||||
|
!!! info "Views"
|
||||||
|
|
||||||
|
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
|
||||||
|
(`<nlohmann/json_view.hpp>`): [`get<T>()`](../basic_json_view/get.md) on a view looks the members up in the
|
||||||
|
view, without building a `json` value first.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: (1) NLOHMANN_DEFINE_TYPE_INTRUSIVE"
|
??? example "Example: (1) NLOHMANN_DEFINE_TYPE_INTRUSIVE"
|
||||||
@@ -189,3 +195,5 @@ See the examples below for the concrete generated code.
|
|||||||
|
|
||||||
All three macros were changed to work with any `basic_json` specialization (not only `nlohmann::json`) in version 3.12.0,
|
All three macros were changed to work with any `basic_json` specialization (not only `nlohmann::json`) in version 3.12.0,
|
||||||
and to allow an empty member list in version 3.13.0.
|
and to allow an empty member list in version 3.13.0.
|
||||||
|
|
||||||
|
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
|
||||||
@@ -80,6 +80,12 @@ See the examples below for the concrete generated code.
|
|||||||
that serializes a struct's members positionally into a JSON array; for that, write `to_json`/`from_json` by
|
that serializes a struct's members positionally into a JSON array; for that, write `to_json`/`from_json` by
|
||||||
hand, building/reading a `json::array()` of the members in order.
|
hand, building/reading a `json::array()` of the members in order.
|
||||||
|
|
||||||
|
!!! info "Views"
|
||||||
|
|
||||||
|
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
|
||||||
|
(`<nlohmann/json_view.hpp>`): [`get<T>()`](../basic_json_view/get.md) on a view looks the members up in the
|
||||||
|
view, without building a `json` value first.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: (1) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE"
|
??? example "Example: (1) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE"
|
||||||
@@ -188,3 +194,5 @@ See the examples below for the concrete generated code.
|
|||||||
|
|
||||||
All three macros were changed to work with any `basic_json` specialization (not only `nlohmann::json`) in version 3.12.0,
|
All three macros were changed to work with any `basic_json` specialization (not only `nlohmann::json`) in version 3.12.0,
|
||||||
and to allow an empty member list in version 3.13.0.
|
and to allow an empty member list in version 3.13.0.
|
||||||
|
|
||||||
|
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
|
||||||
@@ -39,6 +39,6 @@ the library.
|
|||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. Added the ABI tag `_dp` in
|
- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. Added the ABI tag `_dp` in
|
||||||
version 3.12.0, and the ABI tags `_bics`, `_psp`, `_snul`, `_sbu8`, `_ekmo`, `_dsbs`, `_dufio`, `_ns`, `_vns`,
|
version 3.12.0, and the ABI tags `_bics`, `_psp`, `_snul`, `_sbu8`, `_ekmo`, `_dsbs`, `_dufio`, and `_ns` in
|
||||||
and `_vssse3` in version 3.13.0; see
|
version 3.13.0; see
|
||||||
[`nlohmann` Namespace](../../features/namespace.md#structure).
|
[`nlohmann` Namespace](../../features/namespace.md#structure).
|
||||||
@@ -45,6 +45,12 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
|
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
|
||||||
with the converted keys. Such maps can be read from both forms.
|
with the converted keys. Such maps can be read from both forms.
|
||||||
|
|
||||||
|
!!! info "Views"
|
||||||
|
|
||||||
|
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
|
||||||
|
(`<nlohmann/json_view.hpp>`), comparing the view with the entries of the mapping, without building a `json` value
|
||||||
|
first.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: Basic usage"
|
??? example "Example: Basic usage"
|
||||||
@@ -88,3 +94,5 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
Added in version 3.4.0.
|
Added in version 3.4.0.
|
||||||
|
|
||||||
|
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
|
||||||
@@ -48,6 +48,12 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
|
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
|
||||||
with the converted keys. Such maps can be read from both forms.
|
with the converted keys. Such maps can be read from both forms.
|
||||||
|
|
||||||
|
!!! info "Views"
|
||||||
|
|
||||||
|
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
|
||||||
|
(`<nlohmann/json_view.hpp>`), comparing the view with the entries of the mapping, without building a `json` value
|
||||||
|
first.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: Basic usage"
|
??? example "Example: Basic usage"
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using nlohmann::json;
|
||||||
|
|
||||||
|
namespace ns
|
||||||
|
{
|
||||||
|
struct person
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
int age = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// reads json values and views (of any document type), but nothing else
|
||||||
|
template < typename J, typename std::enable_if < nlohmann::is_json_view<J>::value || std::is_same<J, json>::value, int >::type = 0 >
|
||||||
|
void from_json(const J& j, person& p)
|
||||||
|
{
|
||||||
|
p.name = j.at("name").template get<std::string>();
|
||||||
|
p.age = j.at("age").template get<int>();
|
||||||
|
}
|
||||||
|
} // namespace ns
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::cout << std::boolalpha
|
||||||
|
<< nlohmann::is_json_view<nlohmann::json_view>::value << ' '
|
||||||
|
<< nlohmann::is_json_view<nlohmann::ordered_json_editable_view>::value << ' '
|
||||||
|
<< nlohmann::is_json_view<json>::value << '\n';
|
||||||
|
|
||||||
|
const nlohmann::json_document doc = nlohmann::json_document::parse(R"({"name": "Ada", "age": 36})");
|
||||||
|
const auto p = doc.root().get<ns::person>(); // reads the view, no json value is built
|
||||||
|
std::cout << p.name << ' ' << p.age << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
true true false
|
||||||
|
Ada 36
|
||||||
@@ -185,6 +185,10 @@ key as well. Other zero-copy parsers that index the source text, such as yyjson
|
|||||||
member. RFC 8259 only says that names within an object SHOULD be unique and that the behavior of a receiver that sees
|
member. RFC 8259 only says that names within an object SHOULD be unique and that the behavior of a receiver that sees
|
||||||
duplicates is unpredictable, so neither choice is wrong.
|
duplicates is unpredictable, so neither choice is wrong.
|
||||||
|
|
||||||
|
The same holds for [`get<T>()`](../api/basic_json_view/get.md) of a type whose `from_json()` reads the view, such as
|
||||||
|
the types of the `NLOHMANN_DEFINE_TYPE_*` macros: their members are looked up, so `#!cpp get<point>()` of
|
||||||
|
`#!cpp {"x":1,"x":2}` reads `#!cpp x == 1`, while `#!cpp materialize().get<point>()` reads `#!cpp 2`.
|
||||||
|
|
||||||
**What stays the same as `parse()`?** [`materialize()`](../api/basic_json_view/materialize.md) and
|
**What stays the same as `parse()`?** [`materialize()`](../api/basic_json_view/materialize.md) and
|
||||||
[`get<std::map<...>>()`](../api/basic_json_view/get.md) replay every member in order, so they keep the *last* value
|
[`get<std::map<...>>()`](../api/basic_json_view/get.md) replay every member in order, so they keep the *last* value
|
||||||
exactly like `#!cpp basic_json::parse()` (at the position of the first occurrence of the key, for an
|
exactly like `#!cpp basic_json::parse()` (at the position of the first occurrence of the key, for an
|
||||||
@@ -354,9 +358,10 @@ validation entirely, for an image trusted as much as the process's own memory. S
|
|||||||
!!! warning "Experimental"
|
!!! warning "Experimental"
|
||||||
|
|
||||||
The image format is versioned but not yet stable, and may change in an incompatible way before it is declared
|
The image format is versioned but not yet stable, and may change in an incompatible way before it is declared
|
||||||
stable. It is little-endian only, and tied to the library build that wrote it -- use it to cache a document or to
|
stable. It is little-endian only (on big-endian targets, `save()` and `load()` do not exist), and tied to the
|
||||||
hand one to another process running the *same* build, not as a long-term storage format; keep the original JSON
|
library build that wrote it -- use it to cache a document or to hand one to another process running the *same*
|
||||||
text if a saved document needs to be readable by a future library version.
|
build, not as a long-term storage format; keep the original JSON text if a saved document needs to be readable by
|
||||||
|
a future library version.
|
||||||
|
|
||||||
The idea of a document you can read without parsing comes from zero-copy formats such as
|
The idea of a document you can read without parsing comes from zero-copy formats such as
|
||||||
[FlatBuffers](https://github.com/google/flatbuffers) and [YaFF](https://github.com/yandex/yaff); the check
|
[FlatBuffers](https://github.com/google/flatbuffers) and [YaFF](https://github.com/yandex/yaff); the check
|
||||||
|
|||||||
@@ -287,23 +287,6 @@ external dependency and is not defined by default.
|
|||||||
|
|
||||||
See [full documentation of `JSON_USE_SIMDUTF`](../api/macros/json_use_simdutf.md).
|
See [full documentation of `JSON_USE_SIMDUTF`](../api/macros/json_use_simdutf.md).
|
||||||
|
|
||||||
## `JSON_VIEW_NO_SIMD`
|
|
||||||
|
|
||||||
When defined, the parser of [`basic_json_document`](../api/basic_json_document/index.md)
|
|
||||||
(`<nlohmann/json_view.hpp>`) uses only portable C++ to scan strings, instead of vector instructions (SSE2 on x86-64,
|
|
||||||
NEON on AArch64). The same input is accepted or rejected either way; only the speed differs. It is not defined by
|
|
||||||
default.
|
|
||||||
|
|
||||||
See [full documentation of `JSON_VIEW_NO_SIMD`](../api/macros/json_view_no_simd.md).
|
|
||||||
|
|
||||||
## `JSON_VIEW_USE_SSSE3`
|
|
||||||
|
|
||||||
When defined on x86-64, the parser of [`basic_json_document`](../api/basic_json_document/index.md)
|
|
||||||
(`<nlohmann/json_view.hpp>`) validates non-ASCII text in strings with SSSE3 without asking the CPU first. It is not
|
|
||||||
defined by default.
|
|
||||||
|
|
||||||
See [full documentation of `JSON_VIEW_USE_SSSE3`](../api/macros/json_view_use_ssse3.md).
|
|
||||||
|
|
||||||
## `NLOHMANN_DEFINE_TYPE_*(...)`, `NLOHMANN_DEFINE_DERIVED_TYPE_*(...)`
|
## `NLOHMANN_DEFINE_TYPE_*(...)`, `NLOHMANN_DEFINE_DERIVED_TYPE_*(...)`
|
||||||
|
|
||||||
The library defines 12 macros to simplify the serialization/deserialization of types. See the page on
|
The library defines 12 macros to simplify the serialization/deserialization of types. See the page on
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ The complete default namespace name is derived as follows:
|
|||||||
- [`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md) defined non-zero appends
|
- [`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md) defined non-zero appends
|
||||||
`_dufio`.
|
`_dufio`.
|
||||||
- [`JSON_NO_SIMD`](../api/macros/json_no_simd.md) defined appends `_ns`.
|
- [`JSON_NO_SIMD`](../api/macros/json_no_simd.md) defined appends `_ns`.
|
||||||
- [`JSON_VIEW_NO_SIMD`](../api/macros/json_view_no_simd.md) defined appends `_vns`.
|
|
||||||
- [`JSON_VIEW_USE_SSSE3`](../api/macros/json_view_use_ssse3.md) defined appends `_vssse3`.
|
|
||||||
- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by
|
- 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)
|
underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component)
|
||||||
below.
|
below.
|
||||||
@@ -115,7 +113,5 @@ follows:
|
|||||||
([`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md)), `_ekmo`
|
([`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md)), `_ekmo`
|
||||||
([`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md)), `_dsbs`
|
([`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md)), `_dsbs`
|
||||||
([`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md)), `_dufio`
|
([`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md)), `_dufio`
|
||||||
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md)), `_ns`
|
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md)), and `_ns`
|
||||||
([`JSON_NO_SIMD`](../api/macros/json_no_simd.md)), `_vns`
|
([`JSON_NO_SIMD`](../api/macros/json_no_simd.md)) in version 3.13.0.
|
||||||
([`JSON_VIEW_NO_SIMD`](../api/macros/json_view_no_simd.md)), and `_vssse3`
|
|
||||||
([`JSON_VIEW_USE_SSSE3`](../api/macros/json_view_use_ssse3.md)) in version 3.13.0.
|
|
||||||
@@ -21,10 +21,10 @@ ABI tags are not covered and may show raw internal fields instead. To generate a
|
|||||||
```
|
```
|
||||||
|
|
||||||
3. Generate a Natvis file with the tags of your configuration, for example for `JSON_DIAGNOSTICS`,
|
3. Generate a Natvis file with the tags of your configuration, for example for `JSON_DIAGNOSTICS`,
|
||||||
`JSON_DIAGNOSTIC_POSITIONS`, and `JSON_VIEW_NO_SIMD`:
|
`JSON_DIAGNOSTIC_POSITIONS`, and `JSON_NO_SIMD`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my_nlohmann_json.natvis"
|
make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_ns --output my_nlohmann_json.natvis"
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Use the generated file instead of `nlohmann_json.natvis`.
|
4. Use the generated file instead of `nlohmann_json.natvis`.
|
||||||
|
|||||||
@@ -853,17 +853,12 @@ from JSON text.
|
|||||||
|
|
||||||
[`basic_json_document::save()`](../api/basic_json_document/save.md) cannot write an
|
[`basic_json_document::save()`](../api/basic_json_document/save.md) cannot write an
|
||||||
[image](../features/json_view.md#images) of a [discarded](../api/basic_json_document/is_discarded.md) document.
|
[image](../features/json_view.md#images) of a [discarded](../api/basic_json_document/is_discarded.md) document.
|
||||||
[`save()`](../api/basic_json_document/save.md) and [`load()`](../api/basic_json_document/load.md) also throw this
|
|
||||||
exception on a big-endian target, since the image format is little-endian only.
|
|
||||||
|
|
||||||
!!! failure "Example messages"
|
!!! failure "Example messages"
|
||||||
|
|
||||||
```
|
```
|
||||||
[json.exception.type_error.320] cannot save a discarded json_document
|
[json.exception.type_error.320] cannot save a discarded json_document
|
||||||
```
|
```
|
||||||
```
|
|
||||||
[json.exception.type_error.320] json_document images need a little-endian target
|
|
||||||
```
|
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ nav:
|
|||||||
- 'Overview': api/adl_serializer/index.md
|
- 'Overview': api/adl_serializer/index.md
|
||||||
- 'from_json': api/adl_serializer/from_json.md
|
- 'from_json': api/adl_serializer/from_json.md
|
||||||
- 'to_json': api/adl_serializer/to_json.md
|
- 'to_json': api/adl_serializer/to_json.md
|
||||||
|
- 'is_json_view': api/is_json_view.md
|
||||||
- 'json': api/json.md
|
- 'json': api/json.md
|
||||||
- 'json_document': api/json_document.md
|
- 'json_document': api/json_document.md
|
||||||
- 'json_editable_document': api/json_editable_document.md
|
- 'json_editable_document': api/json_editable_document.md
|
||||||
@@ -442,8 +443,6 @@ nav:
|
|||||||
- 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON': api/macros/json_use_legacy_discarded_value_comparison.md
|
- 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON': api/macros/json_use_legacy_discarded_value_comparison.md
|
||||||
- 'JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS': api/macros/json_use_objects_for_enum_keyed_maps.md
|
- 'JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS': api/macros/json_use_objects_for_enum_keyed_maps.md
|
||||||
- 'JSON_USE_SIMDUTF': api/macros/json_use_simdutf.md
|
- 'JSON_USE_SIMDUTF': api/macros/json_use_simdutf.md
|
||||||
- 'JSON_VIEW_NO_SIMD': api/macros/json_view_no_simd.md
|
|
||||||
- 'JSON_VIEW_USE_SSSE3': api/macros/json_view_use_ssse3.md
|
|
||||||
- 'NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_derived_type.md
|
- 'NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_derived_type.md
|
||||||
- 'NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_type_intrusive.md
|
- 'NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_type_intrusive.md
|
||||||
- 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_type_non_intrusive.md
|
- 'NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE': api/macros/nlohmann_define_type_non_intrusive.md
|
||||||
|
|||||||
@@ -128,26 +128,14 @@
|
|||||||
#define NLOHMANN_JSON_ABI_TAG_NO_SIMD
|
#define NLOHMANN_JSON_ABI_TAG_NO_SIMD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JSON_VIEW_NO_SIMD
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD _vns
|
|
||||||
#else
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JSON_VIEW_USE_SSSE3
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3 _vssse3
|
|
||||||
#else
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Construct the namespace ABI tags component
|
// Construct the namespace ABI tags component
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k, l, m) json_abi ## a ## b ## c ## d ## e ## f ## g ## h ## i ## j ## k ## l ## m
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k) json_abi ## a ## b ## c ## d ## e ## f ## g ## h ## i ## j ## k
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h, i, j, k) \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k, l, m)
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k)
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
||||||
@@ -161,9 +149,7 @@
|
|||||||
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS, \
|
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS, \
|
||||||
NLOHMANN_JSON_ABI_TAG_DISABLE_STREAM_BULK_SCAN, \
|
NLOHMANN_JSON_ABI_TAG_DISABLE_STREAM_BULK_SCAN, \
|
||||||
NLOHMANN_JSON_ABI_TAG_DISABLE_UNLOCKED_FILE_IO, \
|
NLOHMANN_JSON_ABI_TAG_DISABLE_UNLOCKED_FILE_IO, \
|
||||||
NLOHMANN_JSON_ABI_TAG_NO_SIMD, \
|
NLOHMANN_JSON_ABI_TAG_NO_SIMD)
|
||||||
NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD, \
|
|
||||||
NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3)
|
|
||||||
|
|
||||||
// Construct the namespace version component
|
// Construct the namespace version component
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <algorithm> // min, transform
|
#include <algorithm> // min, transform
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
|
#include <cstddef> // nullptr_t
|
||||||
#include <forward_list> // forward_list
|
#include <forward_list> // forward_list
|
||||||
#include <iterator> // inserter, front_inserter, end
|
#include <iterator> // inserter, front_inserter, end
|
||||||
#include <map> // map
|
#include <map> // map
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
#include <nlohmann/detail/meta/identity_tag.hpp>
|
#include <nlohmann/detail/meta/identity_tag.hpp>
|
||||||
#include <nlohmann/detail/meta/std_fs.hpp>
|
#include <nlohmann/detail/meta/std_fs.hpp>
|
||||||
#include <nlohmann/detail/meta/type_traits.hpp>
|
#include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
#include <nlohmann/detail/output/error_handler.hpp>
|
||||||
#include <nlohmann/detail/string_concat.hpp>
|
#include <nlohmann/detail/string_concat.hpp>
|
||||||
#include <nlohmann/detail/value_t.hpp>
|
#include <nlohmann/detail/value_t.hpp>
|
||||||
|
|
||||||
@@ -665,16 +667,114 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct from_json_fn
|
namespace from_json_adl
|
||||||
{
|
{
|
||||||
template<typename BasicJsonType, typename T>
|
// hides the library's from_json() overloads above (and the from_json object):
|
||||||
auto operator()(const BasicJsonType& j, T&& val) const
|
// a call from this namespace finds only the from_json() functions of the
|
||||||
|
// arguments' own namespaces and classes (ADL); the declaration is never viable
|
||||||
|
// and never defined (not "= delete", which GCC before 6 reports as a use)
|
||||||
|
struct hidden;
|
||||||
|
void from_json(const hidden&);
|
||||||
|
|
||||||
|
// a type no from_json() written for JSON values accepts: a from_json() that
|
||||||
|
// accepts it is not constrained to them (see has_view_from_json; it lives
|
||||||
|
// here, so that ADL finds no other from_json() for it)
|
||||||
|
struct probe
|
||||||
|
{};
|
||||||
|
|
||||||
|
struct fn
|
||||||
|
{
|
||||||
|
template<typename SourceType, typename T>
|
||||||
|
auto operator()(const SourceType& j, T&& val) const
|
||||||
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
||||||
-> decltype(from_json(j, std::forward<T>(val)))
|
-> decltype(from_json(j, std::forward<T>(val)))
|
||||||
{
|
{
|
||||||
return from_json(j, std::forward<T>(val));
|
return from_json(j, std::forward<T>(val));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} // namespace from_json_adl
|
||||||
|
|
||||||
|
// the sources whose from_json() is only looked up by ADL: views (the library's
|
||||||
|
// overloads are written for basic_json) and the probe
|
||||||
|
template<typename T>
|
||||||
|
struct is_adl_only_from_json_source : disjunction<is_json_view<T>, std::is_same<T, from_json_adl::probe>> {};
|
||||||
|
|
||||||
|
struct from_json_fn
|
||||||
|
{
|
||||||
|
template < typename BasicJsonType, typename T,
|
||||||
|
enable_if_t < !is_adl_only_from_json_source<BasicJsonType>::value, int > = 0 >
|
||||||
|
auto operator()(const BasicJsonType& j, T && val) const
|
||||||
|
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
||||||
|
-> decltype(from_json(j, std::forward<T>(val)))
|
||||||
|
{
|
||||||
|
return from_json(j, std::forward<T>(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename SourceType, typename T,
|
||||||
|
enable_if_t < is_adl_only_from_json_source<SourceType>::value, int > = 0 >
|
||||||
|
auto operator()(const SourceType& j, T && val) const
|
||||||
|
noexcept(noexcept(from_json_adl::fn {}(j, std::forward<T>(val))))
|
||||||
|
-> decltype(from_json_adl::fn {}(j, std::forward<T>(val)))
|
||||||
|
{
|
||||||
|
return from_json_adl::fn {}(j, std::forward<T>(val));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Whether JSONSerializer::from_json(view, T&) reads T from a view (of
|
||||||
|
// <nlohmann/json_view.hpp>) directly: it must accept the view but not the
|
||||||
|
// probe. An unconstrained from_json() template (written for basic_json, but
|
||||||
|
// accepting anything) is thus not called with a view, nor are the library's
|
||||||
|
// own conversions; the view converts such types through materialize().
|
||||||
|
template<typename Serializer, typename SourceType, typename T>
|
||||||
|
using serializer_from_json_t = decltype(Serializer::from_json(std::declval<const SourceType&>(), std::declval<T&>()));
|
||||||
|
|
||||||
|
template<typename Serializer, typename View, typename T>
|
||||||
|
struct has_view_from_json
|
||||||
|
: conjunction < is_detected<serializer_from_json_t, Serializer, View, T>,
|
||||||
|
negation<is_detected<serializer_from_json_t, Serializer, from_json_adl::probe, T>>> {};
|
||||||
|
|
||||||
|
// the base part of a type of the NLOHMANN_DEFINE_DERIVED_TYPE_* macros: from a
|
||||||
|
// view through its get_to(), which reads the base from the view where the
|
||||||
|
// base's from_json() accepts views, and from materialize() otherwise
|
||||||
|
template<typename BasicJsonType, typename T, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
|
void from_json_base(const BasicJsonType& j, T& base)
|
||||||
|
{
|
||||||
|
from_json_fn {}(j, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename View, typename T, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
|
void from_json_base(const View& v, T& base)
|
||||||
|
{
|
||||||
|
v.get_to(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the context of an exception thrown by a from_json() of the macros: the value
|
||||||
|
// itself for basic_json (for JSON_DIAGNOSTICS), none for a view
|
||||||
|
template<typename BasicJsonType, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
|
const BasicJsonType * from_json_context(const BasicJsonType& j) noexcept
|
||||||
|
{
|
||||||
|
return &j;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
|
std::nullptr_t from_json_context(const View& /*unused*/) noexcept
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a value as an exception message shows it (invalid UTF-8 replaced; the
|
||||||
|
// strings of a view are always valid UTF-8)
|
||||||
|
template<typename BasicJsonType, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
|
typename BasicJsonType::string_t from_json_dump(const BasicJsonType& j)
|
||||||
|
{
|
||||||
|
return j.dump(-1, ' ', false, error_handler_t::replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
|
typename View::string_t from_json_dump(const View& v)
|
||||||
|
{
|
||||||
|
return v.dump();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ enum class exception_id : int
|
|||||||
type_not_serializable = 317, ///< a value cannot be serialized to the requested binary format
|
type_not_serializable = 317, ///< a value cannot be serialized to the requested binary format
|
||||||
enum_key_duplicate = 318, ///< an enum-keyed map has two keys that serialize to the same string
|
enum_key_duplicate = 318, ///< an enum-keyed map has two keys that serialize to the same string
|
||||||
document_binary_value = 319, ///< a binary value is stored in a json_document
|
document_binary_value = 319, ///< a binary value is stored in a json_document
|
||||||
document_image_unsupported = 320, ///< a json_document image cannot be saved or loaded (discarded document, big-endian target)
|
document_image_unsupported = 320, ///< a discarded json_document cannot be saved as an image
|
||||||
discarded_value_used = 321, ///< a discarded value is used
|
discarded_value_used = 321, ///< a discarded value is used
|
||||||
// out_of_range
|
// out_of_range
|
||||||
array_index_out_of_range = 401, ///< an array index is out of range
|
array_index_out_of_range = 401, ///< an array index is out of range
|
||||||
|
|||||||
@@ -291,15 +291,17 @@
|
|||||||
}); \
|
}); \
|
||||||
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
|
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
|
||||||
} \
|
} \
|
||||||
template<typename BasicJsonType> \
|
template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> \
|
||||||
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
|
/* (for a view, the table holds basic_json values, which compare with the view) */ \
|
||||||
|
using nlohmann_json_value_t = nlohmann::detail::json_type_of_t<BasicJsonType>; \
|
||||||
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, nlohmann_json_value_t> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, nlohmann_json_value_t>& ej_pair) -> bool \
|
||||||
{ \
|
{ \
|
||||||
return ej_pair.second == j; \
|
return ej_pair.second == j; \
|
||||||
}); \
|
}); \
|
||||||
@@ -330,20 +332,22 @@
|
|||||||
if (it != std::end(m)) j = it->second; \
|
if (it != std::end(m)) j = it->second; \
|
||||||
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range,"enum value out of range for " #ENUM_TYPE, nullptr)); \
|
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range,"enum value out of range for " #ENUM_TYPE, nullptr)); \
|
||||||
} \
|
} \
|
||||||
template<typename BasicJsonType> \
|
template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> \
|
||||||
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
|
/* (for a view, the table holds basic_json values, which compare with the view) */ \
|
||||||
|
using nlohmann_json_value_t = nlohmann::detail::json_type_of_t<BasicJsonType>; \
|
||||||
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, nlohmann_json_value_t> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, nlohmann_json_value_t>& ej_pair) -> bool \
|
||||||
{ \
|
{ \
|
||||||
return ej_pair.second == j; \
|
return ej_pair.second == j; \
|
||||||
}); \
|
}); \
|
||||||
if (it != std::end(m)) e = it->first; \
|
if (it != std::end(m)) e = it->first; \
|
||||||
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", j.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace)), &j)); \
|
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", nlohmann::detail::from_json_dump(j)), nlohmann::detail::from_json_context(j))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
|
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
|
||||||
@@ -603,6 +607,8 @@
|
|||||||
#define NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME(v1, v2) nlohmann_json_t.v2 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(v1, nlohmann_json_default_obj.v2) : nlohmann_json_default_obj.v2;
|
#define NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME(v1, v2) nlohmann_json_t.v2 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(v1, nlohmann_json_default_obj.v2) : nlohmann_json_default_obj.v2;
|
||||||
|
|
||||||
#define NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
#define NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
||||||
|
// from_json() also reads from the views of <nlohmann/json_view.hpp>
|
||||||
|
#define NLOHMANN_JSON_FROM_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
||||||
|
|
||||||
// Helpers used to dispatch the NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_*
|
// Helpers used to dispatch the NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_*
|
||||||
// macros below between a zero-member and a one-or-more-member implementation
|
// macros below between a zero-member and a one-or-more-member implementation
|
||||||
@@ -655,18 +661,18 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType&, Type&) noexcept { })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -676,7 +682,7 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type)
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type)
|
||||||
@@ -685,7 +691,7 @@
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -712,18 +718,18 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType&, Type&) noexcept { })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -733,7 +739,7 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type)
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type)
|
||||||
@@ -742,7 +748,7 @@
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -769,18 +775,18 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -790,7 +796,7 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType)
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType)
|
||||||
@@ -799,7 +805,7 @@
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -827,18 +833,18 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -848,7 +854,7 @@
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType)
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType)
|
||||||
@@ -857,7 +863,7 @@
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
|
|||||||
@@ -340,6 +340,47 @@ template<class B> struct negation : std::integral_constant < bool, !B::value > {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// json_view helpers //
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using basic_json_type_t = typename T::basic_json_type;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using materialize_function_t = decltype(std::declval<const T&>().materialize());
|
||||||
|
|
||||||
|
// a basic_json_view of <nlohmann/json_view.hpp> (detected by its member type
|
||||||
|
// basic_json_type, a basic_json, and materialize() returning that type, so that
|
||||||
|
// json.hpp needs no declaration of the view)
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct is_json_view : std::false_type {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_json_view<T, enable_if_t<is_basic_json<detected_t<basic_json_type_t, T>>::value>>
|
||||||
|
: std::is_same<detected_t<materialize_function_t, T>, basic_json_type_t<T>> {};
|
||||||
|
|
||||||
|
// the types from_json() functions of the NLOHMANN_DEFINE_TYPE_* and
|
||||||
|
// NLOHMANN_JSON_SERIALIZE_ENUM macros read from
|
||||||
|
template<typename T>
|
||||||
|
struct is_basic_json_or_view : disjunction<is_basic_json<T>, is_json_view<T>> {};
|
||||||
|
|
||||||
|
// the basic_json type of a basic_json value or of a view
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct json_type_of
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct json_type_of<T, enable_if_t<is_json_view<T>::value>>
|
||||||
|
{
|
||||||
|
using type = typename T::basic_json_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using json_type_of_t = typename json_type_of<T>::type;
|
||||||
|
|
||||||
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
|
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
|
||||||
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
|
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
|
||||||
// This causes compile errors in e.g., Clang 3.5 or GCC 4.9.
|
// This causes compile errors in e.g., Clang 3.5 or GCC 4.9.
|
||||||
|
|||||||
@@ -182,12 +182,10 @@ inline void compact_nodes(const document_data& d, std::size_t arena_size, std::v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NLOHMANN_VIEW_LITTLE_ENDIAN // (the image format is little-endian: no save() elsewhere)
|
||||||
/// the document as an image
|
/// the document as an image
|
||||||
inline std::vector<std::uint8_t> save_image(const document_data& d)
|
inline std::vector<std::uint8_t> save_image(const document_data& d)
|
||||||
{
|
{
|
||||||
#if !NLOHMANN_VIEW_LITTLE_ENDIAN
|
|
||||||
throw_type_error(exception_id::document_image_unsupported, "json_document images need a little-endian target"); // LCOV_EXCL_LINE
|
|
||||||
#endif
|
|
||||||
const std::size_t arena_size = d.arena_size;
|
const std::size_t arena_size = d.arena_size;
|
||||||
std::vector<node> compacted;
|
std::vector<node> compacted;
|
||||||
std::string text_tail;
|
std::string text_tail;
|
||||||
@@ -243,6 +241,7 @@ inline std::vector<std::uint8_t> save_image(const document_data& d)
|
|||||||
*o = 0;
|
*o = 0;
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// the parts of a number token that the checks need
|
/// the parts of a number token that the checks need
|
||||||
struct number_token
|
struct number_token
|
||||||
@@ -663,13 +662,11 @@ inline bool check_image(const node* nodes, std::size_t count, const unsigned cha
|
|||||||
throw_parse_error(exception_id::invalid_document_image, concat("invalid json_document image: ", what));
|
throw_parse_error(exception_id::invalid_document_image, concat("invalid json_document image: ", what));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NLOHMANN_VIEW_LITTLE_ENDIAN // (the image format is little-endian: no load() elsewhere)
|
||||||
/// Read an image into d. The text and the decoded strings stay in the image;
|
/// Read an image into d. The text and the decoded strings stay in the image;
|
||||||
/// the nodes are copied (so that they are aligned, and edits can change them).
|
/// the nodes are copied (so that they are aligned, and edits can change them).
|
||||||
inline void load_image(document_data& d, const std::uint8_t* image, std::size_t size, image_check check)
|
inline void load_image(document_data& d, const std::uint8_t* image, std::size_t size, image_check check)
|
||||||
{
|
{
|
||||||
#if !NLOHMANN_VIEW_LITTLE_ENDIAN
|
|
||||||
throw_type_error(exception_id::document_image_unsupported, "json_document images need a little-endian target"); // LCOV_EXCL_LINE
|
|
||||||
#endif
|
|
||||||
if (image == nullptr || size < sizeof(image_header))
|
if (image == nullptr || size < sizeof(image_header))
|
||||||
{
|
{
|
||||||
throw_invalid_image("too short");
|
throw_invalid_image("too short");
|
||||||
@@ -738,6 +735,7 @@ inline void load_image(document_data& d, const std::uint8_t* image, std::size_t
|
|||||||
std::vector<std::uint32_t>().swap(d.large_objects); // (only needed while building)
|
std::vector<std::uint32_t>().swap(d.large_objects); // (only needed while building)
|
||||||
d.discarded = false;
|
d.discarded = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace view
|
} // namespace view
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|||||||
@@ -24,25 +24,25 @@
|
|||||||
// with different flags would have different definitions of the same inline
|
// with different flags would have different definitions of the same inline
|
||||||
// functions): the check is compiled for SSSE3 with a function attribute and
|
// functions): the check is compiled for SSSE3 with a function attribute and
|
||||||
// used where the CPU has SSSE3 (all x86-64 CPUs since about 2011), else the
|
// used where the CPU has SSSE3 (all x86-64 CPUs since about 2011), else the
|
||||||
// portable check. JSON_VIEW_USE_SSSE3 skips the CPU check (for code compiled
|
// portable check. Code compiled for SSSE3 anyway (-mssse3 or more) skips the
|
||||||
// for SSSE3 anyway); JSON_VIEW_NO_SIMD selects the portable code.
|
// CPU check. JSON_NO_SIMD selects the portable code, as in the lexer.
|
||||||
// NLOHMANN_VIEW_NO_TARGET_ATTRIBUTE (set by the GCC module interface, where GCC
|
// NLOHMANN_VIEW_NO_TARGET_ATTRIBUTE (set by the GCC module interface, where GCC
|
||||||
// ignores the target attribute and then rejects the SSSE3 intrinsics) keeps the
|
// ignores the target attribute and then rejects the SSSE3 intrinsics) keeps the
|
||||||
// check portable without disabling the SSE2 code.
|
// check portable without disabling the SSE2 code.
|
||||||
#if !defined(JSON_VIEW_NO_SIMD) && defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) && NLOHMANN_VIEW_LITTLE_ENDIAN
|
#if !defined(JSON_NO_SIMD) && defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) && NLOHMANN_VIEW_LITTLE_ENDIAN
|
||||||
#include <arm_neon.h>
|
#include <arm_neon.h>
|
||||||
#define NLOHMANN_VIEW_NEON 1
|
#define NLOHMANN_VIEW_NEON 1
|
||||||
#else
|
#else
|
||||||
#define NLOHMANN_VIEW_NEON 0
|
#define NLOHMANN_VIEW_NEON 0
|
||||||
#endif
|
#endif
|
||||||
// (x86 only: other targets can define __SSE2__ as well, e.g., WebAssembly with -msse2, but have no <cpuid.h>)
|
// (x86 only: other targets can define __SSE2__ as well, e.g., WebAssembly with -msse2, but have no <cpuid.h>)
|
||||||
#if !defined(JSON_VIEW_NO_SIMD) && !NLOHMANN_VIEW_NEON && (defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2))
|
#if !defined(JSON_NO_SIMD) && !NLOHMANN_VIEW_NEON && (defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2))
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#define NLOHMANN_VIEW_SSE2 1
|
#define NLOHMANN_VIEW_SSE2 1
|
||||||
#else
|
#else
|
||||||
#define NLOHMANN_VIEW_SSE2 0
|
#define NLOHMANN_VIEW_SSE2 0
|
||||||
#endif
|
#endif
|
||||||
#if NLOHMANN_VIEW_SSE2 && defined(JSON_VIEW_USE_SSSE3)
|
#if NLOHMANN_VIEW_SSE2 && defined(__SSSE3__)
|
||||||
#include <tmmintrin.h>
|
#include <tmmintrin.h>
|
||||||
#define NLOHMANN_VIEW_SSSE3 1 // NOLINT(cppcoreguidelines-macro-to-enum,modernize-macro-to-enum)
|
#define NLOHMANN_VIEW_SSSE3 1 // NOLINT(cppcoreguidelines-macro-to-enum,modernize-macro-to-enum)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -106,6 +106,8 @@ class basic_json_view
|
|||||||
using navigation = detail::view::navigation<is_editable>;
|
using navigation = detail::view::navigation<is_editable>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// the basic_json type of the document (it also marks views for is_json_view)
|
||||||
|
using basic_json_type = BasicJsonType;
|
||||||
using value_t = detail::value_t;
|
using value_t = detail::value_t;
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
@@ -567,8 +569,10 @@ class basic_json_view
|
|||||||
|
|
||||||
/// the value converted to T, as BasicJsonType::get<T>(): arithmetic types,
|
/// the value converted to T, as BasicJsonType::get<T>(): arithmetic types,
|
||||||
/// strings (string_view_t without a copy), std::nullptr_t, std::vector,
|
/// strings (string_view_t without a copy), std::nullptr_t, std::vector,
|
||||||
/// maps with string keys, and views are converted directly; other types
|
/// maps with string keys, and views are converted directly; types whose
|
||||||
/// through materialize().get<T>()
|
/// from_json() accepts views (those of the NLOHMANN_DEFINE_TYPE_* and
|
||||||
|
/// NLOHMANN_JSON_SERIALIZE_ENUM macros, say) read the view; other types
|
||||||
|
/// go through materialize().get<T>()
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NLOHMANN_VIEW_ALWAYS_INLINE T get() const
|
NLOHMANN_VIEW_ALWAYS_INLINE T get() const
|
||||||
{
|
{
|
||||||
@@ -576,11 +580,12 @@ class basic_json_view
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// as BasicJsonType::get_to(): the types get<T>() converts directly are
|
/// as BasicJsonType::get_to(): the types get<T>() converts directly are
|
||||||
/// assigned, all others are passed to from_json with v as it is
|
/// assigned, all others are passed to from_json with v as it is (with
|
||||||
|
/// the view if from_json() accepts views, else with materialize())
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& get_to(T& v) const
|
T& get_to(T& v) const
|
||||||
{
|
{
|
||||||
get_to_impl(v, detail::view::is_direct_value<T, BasicJsonType, basic_json_view> {});
|
get_to_impl(v, get_to_kind<T> {});
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,6 +928,26 @@ class basic_json_view
|
|||||||
return detail::view::map_value<std::unordered_map<K, V, H, E, A>>(*this);
|
return detail::view::map_value<std::unordered_map<K, V, H, E, A>>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// whether the from_json() of T's serializer reads views (see
|
||||||
|
/// detail::has_view_from_json)
|
||||||
|
template<typename T>
|
||||||
|
using reads_view = detail::has_view_from_json<typename BasicJsonType::template json_serializer<T, void>, basic_json_view, T>;
|
||||||
|
|
||||||
|
/// how get_to() converts: 2 directly, 1 with a from_json() that reads
|
||||||
|
/// views, 0 through materialize()
|
||||||
|
template<typename T>
|
||||||
|
using get_to_kind = std::integral_constant < int, detail::view::is_direct_value<T, BasicJsonType, basic_json_view>::value
|
||||||
|
? 2 : static_cast<int>(reads_view<T>::value) >;
|
||||||
|
|
||||||
|
/// types whose from_json() reads views, without materialize()
|
||||||
|
template < typename T, typename std::enable_if < reads_view<T>::value && std::is_default_constructible<T>::value, int >::type = 0 >
|
||||||
|
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<1> /*unused*/) const
|
||||||
|
{
|
||||||
|
auto v = T();
|
||||||
|
BasicJsonType::template json_serializer<T, void>::from_json(*this, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
/// everything else through the BasicJsonType value (from_json included)
|
/// everything else through the BasicJsonType value (from_json included)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<0> /*unused*/) const
|
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<0> /*unused*/) const
|
||||||
@@ -933,14 +958,20 @@ class basic_json_view
|
|||||||
// --- get_to() dispatch ---
|
// --- get_to() dispatch ---
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void get_to_impl(T& v, std::true_type /*direct*/) const
|
void get_to_impl(T& v, std::integral_constant<int, 2> /*direct*/) const
|
||||||
{
|
{
|
||||||
v = get<T>();
|
v = get<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// from_json may keep parts of v (members a JSON object lacks, say)
|
/// from_json may keep parts of v (members a JSON object lacks, say)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void get_to_impl(T& v, std::false_type /*direct*/) const
|
void get_to_impl(T& v, std::integral_constant<int, 1> /*from_json reads views*/) const
|
||||||
|
{
|
||||||
|
BasicJsonType::template json_serializer<T, void>::from_json(*this, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void get_to_impl(T& v, std::integral_constant<int, 0> /*through materialize()*/) const
|
||||||
{
|
{
|
||||||
materialize().get_to(v);
|
materialize().get_to(v);
|
||||||
}
|
}
|
||||||
@@ -1182,6 +1213,10 @@ class basic_json_document
|
|||||||
/// how load() checks an image (full, bounds, or none)
|
/// how load() checks an image (full, bounds, or none)
|
||||||
using image_check = detail::view::image_check;
|
using image_check = detail::view::image_check;
|
||||||
|
|
||||||
|
#if NLOHMANN_VIEW_LITTLE_ENDIAN
|
||||||
|
// (the image format is little-endian: big-endian targets have no save()
|
||||||
|
// and load(), so that a call fails to compile instead of always throwing)
|
||||||
|
|
||||||
/// The document as an image that load() reads without parsing: the node
|
/// The document as an image that load() reads without parsing: the node
|
||||||
/// index, the text, and the decoded strings. An edited document is
|
/// index, the text, and the decoded strings. An edited document is
|
||||||
/// written in its current state (floats that are not finite become null,
|
/// written in its current state (floats that are not finite become null,
|
||||||
@@ -1223,6 +1258,7 @@ class basic_json_document
|
|||||||
detail::view::load_image(*d.m_data, d.m_data->owned_image.data(), d.m_data->owned_image.size(), check);
|
detail::view::load_image(*d.m_data, d.m_data->owned_image.data(), d.m_data->owned_image.size(), check);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// edits //
|
// edits //
|
||||||
@@ -1640,6 +1676,15 @@ class basic_json_document
|
|||||||
std::unique_ptr<document_data, document_data::deleter> m_data{}; // NOLINT(readability-redundant-member-init)
|
std::unique_ptr<document_data, document_data::deleter> m_data{}; // NOLINT(readability-redundant-member-init)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief whether T is a basic_json_view (of any BasicJsonType and view_mode)
|
||||||
|
|
||||||
|
For constraining templates that accept views, e.g. a from_json() written for
|
||||||
|
both basic_json values and views.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
struct is_json_view : detail::is_json_view<T> {};
|
||||||
|
|
||||||
/// a parsed JSON text for json
|
/// a parsed JSON text for json
|
||||||
using json_document = basic_json_document<json>;
|
using json_document = basic_json_document<json>;
|
||||||
/// a value of a json_document
|
/// a value of a json_document
|
||||||
|
|||||||
Generated
-3700
File diff suppressed because it is too large.
Load diff
Generated
+234
-100
@@ -193,26 +193,14 @@
|
|||||||
#define NLOHMANN_JSON_ABI_TAG_NO_SIMD
|
#define NLOHMANN_JSON_ABI_TAG_NO_SIMD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JSON_VIEW_NO_SIMD
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD _vns
|
|
||||||
#else
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JSON_VIEW_USE_SSSE3
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3 _vssse3
|
|
||||||
#else
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Construct the namespace ABI tags component
|
// Construct the namespace ABI tags component
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k, l, m) json_abi ## a ## b ## c ## d ## e ## f ## g ## h ## i ## j ## k ## l ## m
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k) json_abi ## a ## b ## c ## d ## e ## f ## g ## h ## i ## j ## k
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h, i, j, k) \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k, l, m)
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k)
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
||||||
@@ -226,9 +214,7 @@
|
|||||||
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS, \
|
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS, \
|
||||||
NLOHMANN_JSON_ABI_TAG_DISABLE_STREAM_BULK_SCAN, \
|
NLOHMANN_JSON_ABI_TAG_DISABLE_STREAM_BULK_SCAN, \
|
||||||
NLOHMANN_JSON_ABI_TAG_DISABLE_UNLOCKED_FILE_IO, \
|
NLOHMANN_JSON_ABI_TAG_DISABLE_UNLOCKED_FILE_IO, \
|
||||||
NLOHMANN_JSON_ABI_TAG_NO_SIMD, \
|
NLOHMANN_JSON_ABI_TAG_NO_SIMD)
|
||||||
NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD, \
|
|
||||||
NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3)
|
|
||||||
|
|
||||||
// Construct the namespace version component
|
// Construct the namespace version component
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
||||||
@@ -286,6 +272,7 @@
|
|||||||
|
|
||||||
#include <algorithm> // min, transform
|
#include <algorithm> // min, transform
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
|
#include <cstddef> // nullptr_t
|
||||||
#include <forward_list> // forward_list
|
#include <forward_list> // forward_list
|
||||||
#include <iterator> // inserter, front_inserter, end
|
#include <iterator> // inserter, front_inserter, end
|
||||||
#include <map> // map
|
#include <map> // map
|
||||||
@@ -2677,15 +2664,17 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
}); \
|
}); \
|
||||||
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
|
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
|
||||||
} \
|
} \
|
||||||
template<typename BasicJsonType> \
|
template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> \
|
||||||
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
|
/* (for a view, the table holds basic_json values, which compare with the view) */ \
|
||||||
|
using nlohmann_json_value_t = nlohmann::detail::json_type_of_t<BasicJsonType>; \
|
||||||
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, nlohmann_json_value_t> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, nlohmann_json_value_t>& ej_pair) -> bool \
|
||||||
{ \
|
{ \
|
||||||
return ej_pair.second == j; \
|
return ej_pair.second == j; \
|
||||||
}); \
|
}); \
|
||||||
@@ -2716,20 +2705,22 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
if (it != std::end(m)) j = it->second; \
|
if (it != std::end(m)) j = it->second; \
|
||||||
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range,"enum value out of range for " #ENUM_TYPE, nullptr)); \
|
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range,"enum value out of range for " #ENUM_TYPE, nullptr)); \
|
||||||
} \
|
} \
|
||||||
template<typename BasicJsonType> \
|
template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> \
|
||||||
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
|
/* (for a view, the table holds basic_json values, which compare with the view) */ \
|
||||||
|
using nlohmann_json_value_t = nlohmann::detail::json_type_of_t<BasicJsonType>; \
|
||||||
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, nlohmann_json_value_t> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, nlohmann_json_value_t>& ej_pair) -> bool \
|
||||||
{ \
|
{ \
|
||||||
return ej_pair.second == j; \
|
return ej_pair.second == j; \
|
||||||
}); \
|
}); \
|
||||||
if (it != std::end(m)) e = it->first; \
|
if (it != std::end(m)) e = it->first; \
|
||||||
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", j.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace)), &j)); \
|
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", nlohmann::detail::from_json_dump(j)), nlohmann::detail::from_json_context(j))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
|
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
|
||||||
@@ -2989,6 +2980,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
#define NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME(v1, v2) nlohmann_json_t.v2 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(v1, nlohmann_json_default_obj.v2) : nlohmann_json_default_obj.v2;
|
#define NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME(v1, v2) nlohmann_json_t.v2 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(v1, nlohmann_json_default_obj.v2) : nlohmann_json_default_obj.v2;
|
||||||
|
|
||||||
#define NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
#define NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
||||||
|
// from_json() also reads from the views of <nlohmann/json_view.hpp>
|
||||||
|
#define NLOHMANN_JSON_FROM_TYPE_TEMPLATE(...) template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json_or_view<BasicJsonType>::value, int> = 0> __VA_ARGS__
|
||||||
|
|
||||||
// Helpers used to dispatch the NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_*
|
// Helpers used to dispatch the NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_*
|
||||||
// macros below between a zero-member and a one-or-more-member implementation
|
// macros below between a zero-member and a one-or-more-member implementation
|
||||||
@@ -3041,18 +3034,18 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType&, Type&) noexcept { })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -3062,7 +3055,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type)
|
#define NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_INTRUSIVE_EMPTY(Type)
|
||||||
@@ -3071,7 +3064,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -3098,18 +3091,18 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type&) { nlohmann_json_j = BasicJsonType::object(); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type is used as a declarator type, not in an expression */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType&, Type&) noexcept { })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType&, Type&) noexcept { })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_TYPE_BODY(NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -3119,7 +3112,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type)
|
#define NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type) NLOHMANN_JSON_DEFINE_TYPE_NON_INTRUSIVE_EMPTY(Type)
|
||||||
@@ -3128,7 +3121,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -3155,18 +3148,18 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -3176,7 +3169,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType)
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_INTRUSIVE_EMPTY(Type, BaseType)
|
||||||
@@ -3185,7 +3178,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -3213,18 +3206,18 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) })
|
||||||
|
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); }) \
|
||||||
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
/* NOLINTNEXTLINE(bugprone-macro-parentheses) Type/BaseType are used as declarator types, not in expressions */ \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); })
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DERIVED_TYPE_BODY(NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_, __VA_ARGS__)(__VA_ARGS__))
|
||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -3234,7 +3227,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
*/
|
*/
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_MEMBERS(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(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__)) })
|
||||||
|
|
||||||
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
// identical to NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY: with no members there is nothing to default
|
||||||
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType)
|
#define NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_EMPTY(Type, BaseType) NLOHMANN_JSON_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_EMPTY(Type, BaseType)
|
||||||
@@ -3243,7 +3236,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
|
|
||||||
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(Type, BaseType, ...) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void to_json(BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_TO_WITH_NAME, __VA_ARGS__)) }) \
|
||||||
NLOHMANN_JSON_BASIC_TYPE_TEMPLATE(void from_json(const BasicJsonType& 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_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
NLOHMANN_JSON_FROM_TYPE_TEMPLATE(void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { ::nlohmann::detail::from_json_base(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_DOUBLE_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT_WITH_NAME, __VA_ARGS__)) })
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief macro
|
@brief macro
|
||||||
@@ -4530,6 +4523,47 @@ template<class B> struct negation : std::integral_constant < bool, !B::value > {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// json_view helpers //
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using basic_json_type_t = typename T::basic_json_type;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using materialize_function_t = decltype(std::declval<const T&>().materialize());
|
||||||
|
|
||||||
|
// a basic_json_view of <nlohmann/json_view.hpp> (detected by its member type
|
||||||
|
// basic_json_type, a basic_json, and materialize() returning that type, so that
|
||||||
|
// json.hpp needs no declaration of the view)
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct is_json_view : std::false_type {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_json_view<T, enable_if_t<is_basic_json<detected_t<basic_json_type_t, T>>::value>>
|
||||||
|
: std::is_same<detected_t<materialize_function_t, T>, basic_json_type_t<T>> {};
|
||||||
|
|
||||||
|
// the types from_json() functions of the NLOHMANN_DEFINE_TYPE_* and
|
||||||
|
// NLOHMANN_JSON_SERIALIZE_ENUM macros read from
|
||||||
|
template<typename T>
|
||||||
|
struct is_basic_json_or_view : disjunction<is_basic_json<T>, is_json_view<T>> {};
|
||||||
|
|
||||||
|
// the basic_json type of a basic_json value or of a view
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct json_type_of
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct json_type_of<T, enable_if_t<is_json_view<T>::value>>
|
||||||
|
{
|
||||||
|
using type = typename T::basic_json_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using json_type_of_t = typename json_type_of<T>::type;
|
||||||
|
|
||||||
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
|
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
|
||||||
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
|
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
|
||||||
// This causes compile errors in e.g., Clang 3.5 or GCC 4.9.
|
// This causes compile errors in e.g., Clang 3.5 or GCC 4.9.
|
||||||
@@ -5565,7 +5599,7 @@ enum class exception_id : int
|
|||||||
type_not_serializable = 317, ///< a value cannot be serialized to the requested binary format
|
type_not_serializable = 317, ///< a value cannot be serialized to the requested binary format
|
||||||
enum_key_duplicate = 318, ///< an enum-keyed map has two keys that serialize to the same string
|
enum_key_duplicate = 318, ///< an enum-keyed map has two keys that serialize to the same string
|
||||||
document_binary_value = 319, ///< a binary value is stored in a json_document
|
document_binary_value = 319, ///< a binary value is stored in a json_document
|
||||||
document_image_unsupported = 320, ///< a json_document image cannot be saved or loaded (discarded document, big-endian target)
|
document_image_unsupported = 320, ///< a discarded json_document cannot be saved as an image
|
||||||
discarded_value_used = 321, ///< a discarded value is used
|
discarded_value_used = 321, ///< a discarded value is used
|
||||||
// out_of_range
|
// out_of_range
|
||||||
array_index_out_of_range = 401, ///< an array index is out of range
|
array_index_out_of_range = 401, ///< an array index is out of range
|
||||||
@@ -6049,6 +6083,59 @@ NLOHMANN_JSON_NAMESPACE_END
|
|||||||
|
|
||||||
// #include <nlohmann/detail/meta/type_traits.hpp>
|
// #include <nlohmann/detail/meta/type_traits.hpp>
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/output/error_handler.hpp>
|
||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// #include <nlohmann/detail/abi_macros.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
/// how to treat decoding errors
|
||||||
|
///
|
||||||
|
/// @ref basic_json::dump uses this to decide what to do with ill-formed
|
||||||
|
/// UTF-8 while escaping a string, and the binary writers (@ref
|
||||||
|
/// basic_json::to_cbor, @ref basic_json::to_ubjson, @ref
|
||||||
|
/// basic_json::to_bjdata, @ref basic_json::to_bson) use it the same way for
|
||||||
|
/// string values and object keys. The binary readers (@ref
|
||||||
|
/// basic_json::from_cbor, @ref basic_json::from_msgpack, @ref
|
||||||
|
/// basic_json::from_ubjson, @ref basic_json::from_bjdata, @ref
|
||||||
|
/// basic_json::from_bson) use it to decide whether to check text strings
|
||||||
|
/// and object keys for well-formed UTF-8 at all, since none of those
|
||||||
|
/// formats requires a decoder to do so.
|
||||||
|
enum class error_handler_t
|
||||||
|
{
|
||||||
|
strict, ///< throw a type_error/parse_error exception in case of invalid UTF-8
|
||||||
|
replace, ///< replace invalid UTF-8 sequences with U+FFFD
|
||||||
|
ignore, ///< ignore invalid UTF-8 sequences
|
||||||
|
keep ///< keep invalid UTF-8 sequences unchanged
|
||||||
|
};
|
||||||
|
|
||||||
|
/// the default error handler of the CBOR, UBJSON, BJData, and BSON writers:
|
||||||
|
/// error_handler_t::strict if JSON_STRICT_BINARY_UTF8 is enabled, otherwise
|
||||||
|
/// error_handler_t::keep (the behavior before version 3.13.0)
|
||||||
|
constexpr error_handler_t binary_writer_default_error_handler() noexcept
|
||||||
|
{
|
||||||
|
#if JSON_STRICT_BINARY_UTF8
|
||||||
|
return error_handler_t::strict;
|
||||||
|
#else
|
||||||
|
return error_handler_t::keep;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
// #include <nlohmann/detail/string_concat.hpp>
|
// #include <nlohmann/detail/string_concat.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/value_t.hpp>
|
// #include <nlohmann/detail/value_t.hpp>
|
||||||
@@ -6689,16 +6776,114 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct from_json_fn
|
namespace from_json_adl
|
||||||
{
|
{
|
||||||
template<typename BasicJsonType, typename T>
|
// hides the library's from_json() overloads above (and the from_json object):
|
||||||
auto operator()(const BasicJsonType& j, T&& val) const
|
// a call from this namespace finds only the from_json() functions of the
|
||||||
|
// arguments' own namespaces and classes (ADL); the declaration is never viable
|
||||||
|
// and never defined (not "= delete", which GCC before 6 reports as a use)
|
||||||
|
struct hidden;
|
||||||
|
void from_json(const hidden&);
|
||||||
|
|
||||||
|
// a type no from_json() written for JSON values accepts: a from_json() that
|
||||||
|
// accepts it is not constrained to them (see has_view_from_json; it lives
|
||||||
|
// here, so that ADL finds no other from_json() for it)
|
||||||
|
struct probe
|
||||||
|
{};
|
||||||
|
|
||||||
|
struct fn
|
||||||
|
{
|
||||||
|
template<typename SourceType, typename T>
|
||||||
|
auto operator()(const SourceType& j, T&& val) const
|
||||||
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
||||||
-> decltype(from_json(j, std::forward<T>(val)))
|
-> decltype(from_json(j, std::forward<T>(val)))
|
||||||
{
|
{
|
||||||
return from_json(j, std::forward<T>(val));
|
return from_json(j, std::forward<T>(val));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} // namespace from_json_adl
|
||||||
|
|
||||||
|
// the sources whose from_json() is only looked up by ADL: views (the library's
|
||||||
|
// overloads are written for basic_json) and the probe
|
||||||
|
template<typename T>
|
||||||
|
struct is_adl_only_from_json_source : disjunction<is_json_view<T>, std::is_same<T, from_json_adl::probe>> {};
|
||||||
|
|
||||||
|
struct from_json_fn
|
||||||
|
{
|
||||||
|
template < typename BasicJsonType, typename T,
|
||||||
|
enable_if_t < !is_adl_only_from_json_source<BasicJsonType>::value, int > = 0 >
|
||||||
|
auto operator()(const BasicJsonType& j, T && val) const
|
||||||
|
noexcept(noexcept(from_json(j, std::forward<T>(val))))
|
||||||
|
-> decltype(from_json(j, std::forward<T>(val)))
|
||||||
|
{
|
||||||
|
return from_json(j, std::forward<T>(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename SourceType, typename T,
|
||||||
|
enable_if_t < is_adl_only_from_json_source<SourceType>::value, int > = 0 >
|
||||||
|
auto operator()(const SourceType& j, T && val) const
|
||||||
|
noexcept(noexcept(from_json_adl::fn {}(j, std::forward<T>(val))))
|
||||||
|
-> decltype(from_json_adl::fn {}(j, std::forward<T>(val)))
|
||||||
|
{
|
||||||
|
return from_json_adl::fn {}(j, std::forward<T>(val));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Whether JSONSerializer::from_json(view, T&) reads T from a view (of
|
||||||
|
// <nlohmann/json_view.hpp>) directly: it must accept the view but not the
|
||||||
|
// probe. An unconstrained from_json() template (written for basic_json, but
|
||||||
|
// accepting anything) is thus not called with a view, nor are the library's
|
||||||
|
// own conversions; the view converts such types through materialize().
|
||||||
|
template<typename Serializer, typename SourceType, typename T>
|
||||||
|
using serializer_from_json_t = decltype(Serializer::from_json(std::declval<const SourceType&>(), std::declval<T&>()));
|
||||||
|
|
||||||
|
template<typename Serializer, typename View, typename T>
|
||||||
|
struct has_view_from_json
|
||||||
|
: conjunction < is_detected<serializer_from_json_t, Serializer, View, T>,
|
||||||
|
negation<is_detected<serializer_from_json_t, Serializer, from_json_adl::probe, T>>> {};
|
||||||
|
|
||||||
|
// the base part of a type of the NLOHMANN_DEFINE_DERIVED_TYPE_* macros: from a
|
||||||
|
// view through its get_to(), which reads the base from the view where the
|
||||||
|
// base's from_json() accepts views, and from materialize() otherwise
|
||||||
|
template<typename BasicJsonType, typename T, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
|
void from_json_base(const BasicJsonType& j, T& base)
|
||||||
|
{
|
||||||
|
from_json_fn {}(j, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename View, typename T, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
|
void from_json_base(const View& v, T& base)
|
||||||
|
{
|
||||||
|
v.get_to(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the context of an exception thrown by a from_json() of the macros: the value
|
||||||
|
// itself for basic_json (for JSON_DIAGNOSTICS), none for a view
|
||||||
|
template<typename BasicJsonType, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
|
const BasicJsonType * from_json_context(const BasicJsonType& j) noexcept
|
||||||
|
{
|
||||||
|
return &j;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
|
std::nullptr_t from_json_context(const View& /*unused*/) noexcept
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a value as an exception message shows it (invalid UTF-8 replaced; the
|
||||||
|
// strings of a view are always valid UTF-8)
|
||||||
|
template<typename BasicJsonType, enable_if_t<is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
|
typename BasicJsonType::string_t from_json_dump(const BasicJsonType& j)
|
||||||
|
{
|
||||||
|
return j.dump(-1, ' ', false, error_handler_t::replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
|
typename View::string_t from_json_dump(const View& v)
|
||||||
|
{
|
||||||
|
return v.dump();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
@@ -6793,57 +6978,6 @@ NLOHMANN_JSON_NAMESPACE_END
|
|||||||
// #include <nlohmann/detail/macro_scope.hpp>
|
// #include <nlohmann/detail/macro_scope.hpp>
|
||||||
|
|
||||||
// #include <nlohmann/detail/output/error_handler.hpp>
|
// #include <nlohmann/detail/output/error_handler.hpp>
|
||||||
// __ _____ _____ _____
|
|
||||||
// __| | __| | | | JSON for Modern C++
|
|
||||||
// | | |__ | | | | | | version 3.12.0
|
|
||||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #include <nlohmann/detail/abi_macros.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
/// how to treat decoding errors
|
|
||||||
///
|
|
||||||
/// @ref basic_json::dump uses this to decide what to do with ill-formed
|
|
||||||
/// UTF-8 while escaping a string, and the binary writers (@ref
|
|
||||||
/// basic_json::to_cbor, @ref basic_json::to_ubjson, @ref
|
|
||||||
/// basic_json::to_bjdata, @ref basic_json::to_bson) use it the same way for
|
|
||||||
/// string values and object keys. The binary readers (@ref
|
|
||||||
/// basic_json::from_cbor, @ref basic_json::from_msgpack, @ref
|
|
||||||
/// basic_json::from_ubjson, @ref basic_json::from_bjdata, @ref
|
|
||||||
/// basic_json::from_bson) use it to decide whether to check text strings
|
|
||||||
/// and object keys for well-formed UTF-8 at all, since none of those
|
|
||||||
/// formats requires a decoder to do so.
|
|
||||||
enum class error_handler_t
|
|
||||||
{
|
|
||||||
strict, ///< throw a type_error/parse_error exception in case of invalid UTF-8
|
|
||||||
replace, ///< replace invalid UTF-8 sequences with U+FFFD
|
|
||||||
ignore, ///< ignore invalid UTF-8 sequences
|
|
||||||
keep ///< keep invalid UTF-8 sequences unchanged
|
|
||||||
};
|
|
||||||
|
|
||||||
/// the default error handler of the CBOR, UBJSON, BJData, and BSON writers:
|
|
||||||
/// error_handler_t::strict if JSON_STRICT_BINARY_UTF8 is enabled, otherwise
|
|
||||||
/// error_handler_t::keep (the behavior before version 3.13.0)
|
|
||||||
constexpr error_handler_t binary_writer_default_error_handler() noexcept
|
|
||||||
{
|
|
||||||
#if JSON_STRICT_BINARY_UTF8
|
|
||||||
return error_handler_t::strict;
|
|
||||||
#else
|
|
||||||
return error_handler_t::keep;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
|
||||||
|
|
||||||
|
|
||||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
|||||||
Generated
+4
-18
@@ -145,26 +145,14 @@
|
|||||||
#define NLOHMANN_JSON_ABI_TAG_NO_SIMD
|
#define NLOHMANN_JSON_ABI_TAG_NO_SIMD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JSON_VIEW_NO_SIMD
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD _vns
|
|
||||||
#else
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JSON_VIEW_USE_SSSE3
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3 _vssse3
|
|
||||||
#else
|
|
||||||
#define NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
|
||||||
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Construct the namespace ABI tags component
|
// Construct the namespace ABI tags component
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k, l, m) json_abi ## a ## b ## c ## d ## e ## f ## g ## h ## i ## j ## k ## l ## m
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k) json_abi ## a ## b ## c ## d ## e ## f ## g ## h ## i ## j ## k
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h, i, j, k) \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k, l, m)
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h, i, j, k)
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
||||||
@@ -178,9 +166,7 @@
|
|||||||
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS, \
|
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS, \
|
||||||
NLOHMANN_JSON_ABI_TAG_DISABLE_STREAM_BULK_SCAN, \
|
NLOHMANN_JSON_ABI_TAG_DISABLE_STREAM_BULK_SCAN, \
|
||||||
NLOHMANN_JSON_ABI_TAG_DISABLE_UNLOCKED_FILE_IO, \
|
NLOHMANN_JSON_ABI_TAG_DISABLE_UNLOCKED_FILE_IO, \
|
||||||
NLOHMANN_JSON_ABI_TAG_NO_SIMD, \
|
NLOHMANN_JSON_ABI_TAG_NO_SIMD)
|
||||||
NLOHMANN_JSON_ABI_TAG_VIEW_NO_SIMD, \
|
|
||||||
NLOHMANN_JSON_ABI_TAG_VIEW_USE_SSSE3)
|
|
||||||
|
|
||||||
// Construct the namespace version component
|
// Construct the namespace version component
|
||||||
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
|
||||||
|
|||||||
Generated
+60
-17
@@ -678,25 +678,25 @@ NLOHMANN_JSON_NAMESPACE_END
|
|||||||
// with different flags would have different definitions of the same inline
|
// with different flags would have different definitions of the same inline
|
||||||
// functions): the check is compiled for SSSE3 with a function attribute and
|
// functions): the check is compiled for SSSE3 with a function attribute and
|
||||||
// used where the CPU has SSSE3 (all x86-64 CPUs since about 2011), else the
|
// used where the CPU has SSSE3 (all x86-64 CPUs since about 2011), else the
|
||||||
// portable check. JSON_VIEW_USE_SSSE3 skips the CPU check (for code compiled
|
// portable check. Code compiled for SSSE3 anyway (-mssse3 or more) skips the
|
||||||
// for SSSE3 anyway); JSON_VIEW_NO_SIMD selects the portable code.
|
// CPU check. JSON_NO_SIMD selects the portable code, as in the lexer.
|
||||||
// NLOHMANN_VIEW_NO_TARGET_ATTRIBUTE (set by the GCC module interface, where GCC
|
// NLOHMANN_VIEW_NO_TARGET_ATTRIBUTE (set by the GCC module interface, where GCC
|
||||||
// ignores the target attribute and then rejects the SSSE3 intrinsics) keeps the
|
// ignores the target attribute and then rejects the SSSE3 intrinsics) keeps the
|
||||||
// check portable without disabling the SSE2 code.
|
// check portable without disabling the SSE2 code.
|
||||||
#if !defined(JSON_VIEW_NO_SIMD) && defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) && NLOHMANN_VIEW_LITTLE_ENDIAN
|
#if !defined(JSON_NO_SIMD) && defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) && NLOHMANN_VIEW_LITTLE_ENDIAN
|
||||||
#include <arm_neon.h>
|
#include <arm_neon.h>
|
||||||
#define NLOHMANN_VIEW_NEON 1
|
#define NLOHMANN_VIEW_NEON 1
|
||||||
#else
|
#else
|
||||||
#define NLOHMANN_VIEW_NEON 0
|
#define NLOHMANN_VIEW_NEON 0
|
||||||
#endif
|
#endif
|
||||||
// (x86 only: other targets can define __SSE2__ as well, e.g., WebAssembly with -msse2, but have no <cpuid.h>)
|
// (x86 only: other targets can define __SSE2__ as well, e.g., WebAssembly with -msse2, but have no <cpuid.h>)
|
||||||
#if !defined(JSON_VIEW_NO_SIMD) && !NLOHMANN_VIEW_NEON && (defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2))
|
#if !defined(JSON_NO_SIMD) && !NLOHMANN_VIEW_NEON && (defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2))
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#define NLOHMANN_VIEW_SSE2 1
|
#define NLOHMANN_VIEW_SSE2 1
|
||||||
#else
|
#else
|
||||||
#define NLOHMANN_VIEW_SSE2 0
|
#define NLOHMANN_VIEW_SSE2 0
|
||||||
#endif
|
#endif
|
||||||
#if NLOHMANN_VIEW_SSE2 && defined(JSON_VIEW_USE_SSSE3)
|
#if NLOHMANN_VIEW_SSE2 && defined(__SSSE3__)
|
||||||
#include <tmmintrin.h>
|
#include <tmmintrin.h>
|
||||||
#define NLOHMANN_VIEW_SSSE3 1 // NOLINT(cppcoreguidelines-macro-to-enum,modernize-macro-to-enum)
|
#define NLOHMANN_VIEW_SSSE3 1 // NOLINT(cppcoreguidelines-macro-to-enum,modernize-macro-to-enum)
|
||||||
#else
|
#else
|
||||||
@@ -5007,12 +5007,10 @@ inline void compact_nodes(const document_data& d, std::size_t arena_size, std::v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NLOHMANN_VIEW_LITTLE_ENDIAN // (the image format is little-endian: no save() elsewhere)
|
||||||
/// the document as an image
|
/// the document as an image
|
||||||
inline std::vector<std::uint8_t> save_image(const document_data& d)
|
inline std::vector<std::uint8_t> save_image(const document_data& d)
|
||||||
{
|
{
|
||||||
#if !NLOHMANN_VIEW_LITTLE_ENDIAN
|
|
||||||
throw_type_error(exception_id::document_image_unsupported, "json_document images need a little-endian target"); // LCOV_EXCL_LINE
|
|
||||||
#endif
|
|
||||||
const std::size_t arena_size = d.arena_size;
|
const std::size_t arena_size = d.arena_size;
|
||||||
std::vector<node> compacted;
|
std::vector<node> compacted;
|
||||||
std::string text_tail;
|
std::string text_tail;
|
||||||
@@ -5068,6 +5066,7 @@ inline std::vector<std::uint8_t> save_image(const document_data& d)
|
|||||||
*o = 0;
|
*o = 0;
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// the parts of a number token that the checks need
|
/// the parts of a number token that the checks need
|
||||||
struct number_token
|
struct number_token
|
||||||
@@ -5488,13 +5487,11 @@ inline bool check_image(const node* nodes, std::size_t count, const unsigned cha
|
|||||||
throw_parse_error(exception_id::invalid_document_image, concat("invalid json_document image: ", what));
|
throw_parse_error(exception_id::invalid_document_image, concat("invalid json_document image: ", what));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NLOHMANN_VIEW_LITTLE_ENDIAN // (the image format is little-endian: no load() elsewhere)
|
||||||
/// Read an image into d. The text and the decoded strings stay in the image;
|
/// Read an image into d. The text and the decoded strings stay in the image;
|
||||||
/// the nodes are copied (so that they are aligned, and edits can change them).
|
/// the nodes are copied (so that they are aligned, and edits can change them).
|
||||||
inline void load_image(document_data& d, const std::uint8_t* image, std::size_t size, image_check check)
|
inline void load_image(document_data& d, const std::uint8_t* image, std::size_t size, image_check check)
|
||||||
{
|
{
|
||||||
#if !NLOHMANN_VIEW_LITTLE_ENDIAN
|
|
||||||
throw_type_error(exception_id::document_image_unsupported, "json_document images need a little-endian target"); // LCOV_EXCL_LINE
|
|
||||||
#endif
|
|
||||||
if (image == nullptr || size < sizeof(image_header))
|
if (image == nullptr || size < sizeof(image_header))
|
||||||
{
|
{
|
||||||
throw_invalid_image("too short");
|
throw_invalid_image("too short");
|
||||||
@@ -5563,6 +5560,7 @@ inline void load_image(document_data& d, const std::uint8_t* image, std::size_t
|
|||||||
std::vector<std::uint32_t>().swap(d.large_objects); // (only needed while building)
|
std::vector<std::uint32_t>().swap(d.large_objects); // (only needed while building)
|
||||||
d.discarded = false;
|
d.discarded = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace view
|
} // namespace view
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@@ -7835,6 +7833,8 @@ class basic_json_view
|
|||||||
using navigation = detail::view::navigation<is_editable>;
|
using navigation = detail::view::navigation<is_editable>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// the basic_json type of the document (it also marks views for is_json_view)
|
||||||
|
using basic_json_type = BasicJsonType;
|
||||||
using value_t = detail::value_t;
|
using value_t = detail::value_t;
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
@@ -8296,8 +8296,10 @@ class basic_json_view
|
|||||||
|
|
||||||
/// the value converted to T, as BasicJsonType::get<T>(): arithmetic types,
|
/// the value converted to T, as BasicJsonType::get<T>(): arithmetic types,
|
||||||
/// strings (string_view_t without a copy), std::nullptr_t, std::vector,
|
/// strings (string_view_t without a copy), std::nullptr_t, std::vector,
|
||||||
/// maps with string keys, and views are converted directly; other types
|
/// maps with string keys, and views are converted directly; types whose
|
||||||
/// through materialize().get<T>()
|
/// from_json() accepts views (those of the NLOHMANN_DEFINE_TYPE_* and
|
||||||
|
/// NLOHMANN_JSON_SERIALIZE_ENUM macros, say) read the view; other types
|
||||||
|
/// go through materialize().get<T>()
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NLOHMANN_VIEW_ALWAYS_INLINE T get() const
|
NLOHMANN_VIEW_ALWAYS_INLINE T get() const
|
||||||
{
|
{
|
||||||
@@ -8305,11 +8307,12 @@ class basic_json_view
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// as BasicJsonType::get_to(): the types get<T>() converts directly are
|
/// as BasicJsonType::get_to(): the types get<T>() converts directly are
|
||||||
/// assigned, all others are passed to from_json with v as it is
|
/// assigned, all others are passed to from_json with v as it is (with
|
||||||
|
/// the view if from_json() accepts views, else with materialize())
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& get_to(T& v) const
|
T& get_to(T& v) const
|
||||||
{
|
{
|
||||||
get_to_impl(v, detail::view::is_direct_value<T, BasicJsonType, basic_json_view> {});
|
get_to_impl(v, get_to_kind<T> {});
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8652,6 +8655,26 @@ class basic_json_view
|
|||||||
return detail::view::map_value<std::unordered_map<K, V, H, E, A>>(*this);
|
return detail::view::map_value<std::unordered_map<K, V, H, E, A>>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// whether the from_json() of T's serializer reads views (see
|
||||||
|
/// detail::has_view_from_json)
|
||||||
|
template<typename T>
|
||||||
|
using reads_view = detail::has_view_from_json<typename BasicJsonType::template json_serializer<T, void>, basic_json_view, T>;
|
||||||
|
|
||||||
|
/// how get_to() converts: 2 directly, 1 with a from_json() that reads
|
||||||
|
/// views, 0 through materialize()
|
||||||
|
template<typename T>
|
||||||
|
using get_to_kind = std::integral_constant < int, detail::view::is_direct_value<T, BasicJsonType, basic_json_view>::value
|
||||||
|
? 2 : static_cast<int>(reads_view<T>::value) >;
|
||||||
|
|
||||||
|
/// types whose from_json() reads views, without materialize()
|
||||||
|
template < typename T, typename std::enable_if < reads_view<T>::value && std::is_default_constructible<T>::value, int >::type = 0 >
|
||||||
|
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<1> /*unused*/) const
|
||||||
|
{
|
||||||
|
auto v = T();
|
||||||
|
BasicJsonType::template json_serializer<T, void>::from_json(*this, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
/// everything else through the BasicJsonType value (from_json included)
|
/// everything else through the BasicJsonType value (from_json included)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<0> /*unused*/) const
|
T get_impl(detail::view::value_tag<T> /*unused*/, detail::priority_tag<0> /*unused*/) const
|
||||||
@@ -8662,14 +8685,20 @@ class basic_json_view
|
|||||||
// --- get_to() dispatch ---
|
// --- get_to() dispatch ---
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void get_to_impl(T& v, std::true_type /*direct*/) const
|
void get_to_impl(T& v, std::integral_constant<int, 2> /*direct*/) const
|
||||||
{
|
{
|
||||||
v = get<T>();
|
v = get<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// from_json may keep parts of v (members a JSON object lacks, say)
|
/// from_json may keep parts of v (members a JSON object lacks, say)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void get_to_impl(T& v, std::false_type /*direct*/) const
|
void get_to_impl(T& v, std::integral_constant<int, 1> /*from_json reads views*/) const
|
||||||
|
{
|
||||||
|
BasicJsonType::template json_serializer<T, void>::from_json(*this, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void get_to_impl(T& v, std::integral_constant<int, 0> /*through materialize()*/) const
|
||||||
{
|
{
|
||||||
materialize().get_to(v);
|
materialize().get_to(v);
|
||||||
}
|
}
|
||||||
@@ -8911,6 +8940,10 @@ class basic_json_document
|
|||||||
/// how load() checks an image (full, bounds, or none)
|
/// how load() checks an image (full, bounds, or none)
|
||||||
using image_check = detail::view::image_check;
|
using image_check = detail::view::image_check;
|
||||||
|
|
||||||
|
#if NLOHMANN_VIEW_LITTLE_ENDIAN
|
||||||
|
// (the image format is little-endian: big-endian targets have no save()
|
||||||
|
// and load(), so that a call fails to compile instead of always throwing)
|
||||||
|
|
||||||
/// The document as an image that load() reads without parsing: the node
|
/// The document as an image that load() reads without parsing: the node
|
||||||
/// index, the text, and the decoded strings. An edited document is
|
/// index, the text, and the decoded strings. An edited document is
|
||||||
/// written in its current state (floats that are not finite become null,
|
/// written in its current state (floats that are not finite become null,
|
||||||
@@ -8952,6 +8985,7 @@ class basic_json_document
|
|||||||
detail::view::load_image(*d.m_data, d.m_data->owned_image.data(), d.m_data->owned_image.size(), check);
|
detail::view::load_image(*d.m_data, d.m_data->owned_image.data(), d.m_data->owned_image.size(), check);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// edits //
|
// edits //
|
||||||
@@ -9369,6 +9403,15 @@ class basic_json_document
|
|||||||
std::unique_ptr<document_data, document_data::deleter> m_data{}; // NOLINT(readability-redundant-member-init)
|
std::unique_ptr<document_data, document_data::deleter> m_data{}; // NOLINT(readability-redundant-member-init)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief whether T is a basic_json_view (of any BasicJsonType and view_mode)
|
||||||
|
|
||||||
|
For constraining templates that accept views, e.g. a from_json() written for
|
||||||
|
both basic_json values and views.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
struct is_json_view : detail::is_json_view<T> {};
|
||||||
|
|
||||||
/// a parsed JSON text for json
|
/// a parsed JSON text for json
|
||||||
using json_document = basic_json_document<json>;
|
using json_document = basic_json_document<json>;
|
||||||
/// a value of a json_document
|
/// a value of a json_document
|
||||||
|
|||||||
@@ -420,9 +420,9 @@ json_test_add_test_for(src/unit-file_input.cpp
|
|||||||
)
|
)
|
||||||
|
|
||||||
# the json_view parser again with the portable string scanning instead of
|
# the json_view parser again with the portable string scanning instead of
|
||||||
# NEON/SSE2, and on x86-64 with the SSSE3 UTF-8 check (JSON_VIEW_USE_SSSE3)
|
# NEON/SSE2 (JSON_NO_SIMD), and on x86-64 compiled for SSSE3 (no CPU check)
|
||||||
json_test_set_test_options(test-json_view_builder_portable
|
json_test_set_test_options(test-json_view_builder_portable
|
||||||
COMPILE_DEFINITIONS JSON_VIEW_NO_SIMD
|
COMPILE_DEFINITIONS JSON_NO_SIMD
|
||||||
)
|
)
|
||||||
json_test_add_test_for(src/unit-json_view_builder.cpp
|
json_test_add_test_for(src/unit-json_view_builder.cpp
|
||||||
NAME test-json_view_builder_portable
|
NAME test-json_view_builder_portable
|
||||||
@@ -430,7 +430,6 @@ json_test_add_test_for(src/unit-json_view_builder.cpp
|
|||||||
)
|
)
|
||||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64|amd64)$" AND NOT MSVC)
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64|amd64)$" AND NOT MSVC)
|
||||||
json_test_set_test_options(test-json_view_builder_ssse3
|
json_test_set_test_options(test-json_view_builder_ssse3
|
||||||
COMPILE_DEFINITIONS JSON_VIEW_USE_SSSE3
|
|
||||||
COMPILE_OPTIONS -mssse3
|
COMPILE_OPTIONS -mssse3
|
||||||
)
|
)
|
||||||
json_test_add_test_for(src/unit-json_view_builder.cpp
|
json_test_add_test_for(src/unit-json_view_builder.cpp
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ foreach(test default noversion)
|
|||||||
JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1
|
JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1
|
||||||
JSON_DISABLE_STREAM_BULK_SCAN=1
|
JSON_DISABLE_STREAM_BULK_SCAN=1
|
||||||
JSON_DISABLE_UNLOCKED_FILE_IO=1
|
JSON_DISABLE_UNLOCKED_FILE_IO=1
|
||||||
JSON_NO_SIMD
|
JSON_NO_SIMD)
|
||||||
JSON_VIEW_NO_SIMD
|
|
||||||
JSON_VIEW_USE_SSSE3)
|
|
||||||
target_link_libraries(abi_config_${test}_all_tags PRIVATE abi_compat_main)
|
target_link_libraries(abi_config_${test}_all_tags PRIVATE abi_compat_main)
|
||||||
add_test(
|
add_test(
|
||||||
NAME test-abi_config_${test}_all_tags
|
NAME test-abi_config_${test}_all_tags
|
||||||
|
|||||||
@@ -64,14 +64,6 @@ TEST_CASE("default namespace")
|
|||||||
expected += "_ns";
|
expected += "_ns";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JSON_VIEW_NO_SIMD
|
|
||||||
expected += "_vns";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JSON_VIEW_USE_SSSE3
|
|
||||||
expected += "_vssse3";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
expected += "_v" STRINGIZE(NLOHMANN_JSON_VERSION_MAJOR);
|
expected += "_v" STRINGIZE(NLOHMANN_JSON_VERSION_MAJOR);
|
||||||
expected += "_" STRINGIZE(NLOHMANN_JSON_VERSION_MINOR);
|
expected += "_" STRINGIZE(NLOHMANN_JSON_VERSION_MINOR);
|
||||||
expected += "_" STRINGIZE(NLOHMANN_JSON_VERSION_PATCH) "::basic_json";
|
expected += "_" STRINGIZE(NLOHMANN_JSON_VERSION_PATCH) "::basic_json";
|
||||||
|
|||||||
@@ -65,14 +65,6 @@ TEST_CASE("default namespace without version component")
|
|||||||
expected += "_ns";
|
expected += "_ns";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JSON_VIEW_NO_SIMD
|
|
||||||
expected += "_vns";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JSON_VIEW_USE_SSSE3
|
|
||||||
expected += "_vssse3";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
expected += "::basic_json";
|
expected += "::basic_json";
|
||||||
|
|
||||||
// fallback for Clang
|
// fallback for Clang
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ An editable `json_document` edits in place; yyjson copies its immutable document
|
|||||||
(`yyjson_doc_mut_copy`); Boost.JSON and `json::parse` build mutable DOMs; simdjson cannot edit a document. All
|
(`yyjson_doc_mut_copy`); Boost.JSON and `json::parse` build mutable DOMs; simdjson cannot edit a document. All
|
||||||
outputs are checked to describe the same value.
|
outputs are checked to describe the same value.
|
||||||
|
|
||||||
|
`bench_decode.cpp` measures decoding into structs whose `from_json()` comes from the `NLOHMANN_DEFINE_TYPE_*` macros
|
||||||
|
(twitter statuses, citm_catalog performances, and 20,000 synthetic records): `get<T>()` on a view, which reads the
|
||||||
|
view directly, against `materialize().get<T>()`, `json::parse` plus `get<T>()`, and `get<T>()` on an already parsed
|
||||||
|
`json` value. Only nlohmann/json takes part, as the other libraries have no comparable mapping; all engines are
|
||||||
|
checked to decode the same values.
|
||||||
|
|
||||||
Before anything is timed, all engines must accept each document and agree on the traversal: the number of values, the
|
Before anything is timed, all engines must accept each document and agree on the traversal: the number of values, the
|
||||||
bytes of all strings and keys, and the sum of all numbers. All engines run interleaved in every round, and the best
|
bytes of all strings and keys, and the sum of all numbers. All engines run interleaved in every round, and the best
|
||||||
round is reported, as time and as a factor of the `json_view` time (below 1 means faster than `json_view`). Each timed
|
round is reported, as time and as a factor of the `json_view` time (below 1 means faster than `json_view`). Each timed
|
||||||
|
|||||||
@@ -0,0 +1,312 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
// Decoding into structs: the same types, with from_json() generated by the
|
||||||
|
// NLOHMANN_DEFINE_TYPE_* macros, read three ways. Only nlohmann/json takes
|
||||||
|
// part; the other libraries have no comparable mapping.
|
||||||
|
//
|
||||||
|
// view json_document::parse, then get<T>() on the view (from_json reads the view)
|
||||||
|
// materialize json_document::parse, then materialize().get<T>() (a json value first)
|
||||||
|
// json::parse json::parse, then get<T>()
|
||||||
|
// json::get get<T>() on an already parsed json value (the decoding alone)
|
||||||
|
//
|
||||||
|
// Documents: twitter (the statuses with their users and hashtags), citm_catalog
|
||||||
|
// (the performances with their seat categories), and a synthetic document of
|
||||||
|
// 20,000 nested records.
|
||||||
|
//
|
||||||
|
// Build: see README.md (same flags as bench_view.cpp).
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using nlohmann::json;
|
||||||
|
using nlohmann::json_document;
|
||||||
|
|
||||||
|
static volatile std::size_t g_sink;
|
||||||
|
|
||||||
|
namespace twitter
|
||||||
|
{
|
||||||
|
struct hashtag
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
std::vector<int> indices;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(hashtag, text, indices)
|
||||||
|
|
||||||
|
struct entities
|
||||||
|
{
|
||||||
|
std::vector<hashtag> hashtags;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(entities, hashtags)
|
||||||
|
|
||||||
|
struct user
|
||||||
|
{
|
||||||
|
std::uint64_t id = 0;
|
||||||
|
std::string screen_name;
|
||||||
|
std::string description;
|
||||||
|
std::int64_t followers_count = 0;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(user, id, screen_name, description, followers_count)
|
||||||
|
|
||||||
|
struct status
|
||||||
|
{
|
||||||
|
std::uint64_t id = 0;
|
||||||
|
std::string text;
|
||||||
|
user user;
|
||||||
|
entities entities;
|
||||||
|
std::int64_t retweet_count = 0;
|
||||||
|
std::int64_t favorite_count = 0;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(status, id, text, user, entities, retweet_count, favorite_count)
|
||||||
|
|
||||||
|
struct document
|
||||||
|
{
|
||||||
|
std::vector<status> statuses;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(document, statuses)
|
||||||
|
|
||||||
|
std::size_t digest(const document& d)
|
||||||
|
{
|
||||||
|
std::size_t n = 0;
|
||||||
|
for (const auto& s : d.statuses)
|
||||||
|
{
|
||||||
|
n += s.text.size() + s.user.screen_name.size() + s.entities.hashtags.size() + static_cast<std::size_t>(s.retweet_count);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
} // namespace twitter
|
||||||
|
|
||||||
|
namespace citm
|
||||||
|
{
|
||||||
|
struct area
|
||||||
|
{
|
||||||
|
std::int64_t areaId = 0;
|
||||||
|
std::vector<std::int64_t> blockIds;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(area, areaId, blockIds)
|
||||||
|
|
||||||
|
struct seat_category
|
||||||
|
{
|
||||||
|
std::vector<area> areas;
|
||||||
|
std::int64_t seatCategoryId = 0;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(seat_category, areas, seatCategoryId)
|
||||||
|
|
||||||
|
struct performance
|
||||||
|
{
|
||||||
|
std::int64_t id = 0;
|
||||||
|
std::int64_t eventId = 0;
|
||||||
|
std::vector<seat_category> seatCategories;
|
||||||
|
std::int64_t start = 0;
|
||||||
|
std::string venueCode;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(performance, id, eventId, seatCategories, start, venueCode)
|
||||||
|
|
||||||
|
struct document
|
||||||
|
{
|
||||||
|
std::vector<performance> performances;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(document, performances)
|
||||||
|
|
||||||
|
std::size_t digest(const document& d)
|
||||||
|
{
|
||||||
|
std::size_t n = 0;
|
||||||
|
for (const auto& p : d.performances)
|
||||||
|
{
|
||||||
|
n += p.seatCategories.size() + p.venueCode.size() + static_cast<std::size_t>(p.start % 1000);
|
||||||
|
for (const auto& c : p.seatCategories)
|
||||||
|
{
|
||||||
|
n += c.areas.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
} // namespace citm
|
||||||
|
|
||||||
|
namespace synthetic
|
||||||
|
{
|
||||||
|
struct position
|
||||||
|
{
|
||||||
|
double x = 0;
|
||||||
|
double y = 0;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(position, x, y)
|
||||||
|
|
||||||
|
struct child
|
||||||
|
{
|
||||||
|
std::int64_t id = 0;
|
||||||
|
std::string label;
|
||||||
|
bool active = false;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(child, id, label, active)
|
||||||
|
|
||||||
|
struct record
|
||||||
|
{
|
||||||
|
std::int64_t id = 0;
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> tags;
|
||||||
|
position pos;
|
||||||
|
std::vector<child> children;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(record, id, name, tags, pos, children)
|
||||||
|
|
||||||
|
struct document
|
||||||
|
{
|
||||||
|
std::vector<record> records;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(document, records)
|
||||||
|
|
||||||
|
std::string make_text(std::size_t n)
|
||||||
|
{
|
||||||
|
std::string s = "{\"records\":[";
|
||||||
|
for (std::size_t i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
const std::string id = std::to_string(i);
|
||||||
|
s += (i == 0 ? "" : ",");
|
||||||
|
s += "{\"id\":" + id + ",\"name\":\"record number " + id + "\",\"tags\":[\"alpha\",\"beta\",\"gamma\"],";
|
||||||
|
s += "\"pos\":{\"x\":" + id + ".25,\"y\":-" + id + ".5},\"children\":[";
|
||||||
|
for (std::size_t k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
s += (k == 0 ? "" : ",");
|
||||||
|
s += "{\"id\":" + std::to_string(i * 3 + k) + ",\"label\":\"child " + std::to_string(k) + "\",\"active\":" + (k % 2 == 0 ? "true" : "false") + "}";
|
||||||
|
}
|
||||||
|
s += "]}";
|
||||||
|
}
|
||||||
|
s += "]}";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t digest(const document& d)
|
||||||
|
{
|
||||||
|
std::size_t n = 0;
|
||||||
|
for (const auto& r : d.records)
|
||||||
|
{
|
||||||
|
n += r.name.size() + r.tags.size() + r.children.size() + static_cast<std::size_t>(r.pos.x);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
} // namespace synthetic
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::string read_file(const std::string& p)
|
||||||
|
{
|
||||||
|
std::ifstream f(p, std::ios::binary);
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "cannot open %s\n", p.c_str());
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << f.rdbuf();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
double time_ns(const std::function<void()>& f)
|
||||||
|
{
|
||||||
|
const auto t0 = std::chrono::steady_clock::now();
|
||||||
|
f();
|
||||||
|
const auto t1 = std::chrono::steady_clock::now();
|
||||||
|
return static_cast<double>(std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct engine
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::function<std::size_t()> run;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Document>
|
||||||
|
std::vector<engine> engines(const std::string& text, const json& parsed)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
{
|
||||||
|
{"view", [&text] { const json_document d = json_document::parse(text); return digest(d.root().get<Document>()); }},
|
||||||
|
{"materialize", [&text] { const json_document d = json_document::parse(text); return digest(d.root().materialize().get<Document>()); }},
|
||||||
|
{"json::parse", [&text] { return digest(json::parse(text).get<Document>()); }},
|
||||||
|
{"json::get", [&parsed] { return digest(parsed.get<Document>()); }},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "usage: %s <json_test_data directory> [rounds]\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const std::string dir = argv[1];
|
||||||
|
const int rounds = argc > 2 ? std::max(1, std::atoi(argv[2])) : 30;
|
||||||
|
|
||||||
|
struct document_case
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::string text;
|
||||||
|
json parsed;
|
||||||
|
std::vector<engine> engines;
|
||||||
|
};
|
||||||
|
std::vector<document_case> cases;
|
||||||
|
cases.push_back({"twitter", read_file(dir + "/nativejson-benchmark/twitter.json"), json(), {}});
|
||||||
|
cases.push_back({"citm_catalog", read_file(dir + "/nativejson-benchmark/citm_catalog.json"), json(), {}});
|
||||||
|
cases.push_back({"synthetic", synthetic::make_text(20000), json(), {}});
|
||||||
|
for (auto& c : cases)
|
||||||
|
{
|
||||||
|
c.parsed = json::parse(c.text);
|
||||||
|
}
|
||||||
|
cases[0].engines = engines<twitter::document>(cases[0].text, cases[0].parsed);
|
||||||
|
cases[1].engines = engines<citm::document>(cases[1].text, cases[1].parsed);
|
||||||
|
cases[2].engines = engines<synthetic::document>(cases[2].text, cases[2].parsed);
|
||||||
|
|
||||||
|
std::FILE* csv = std::fopen("bench_decode.csv", "w");
|
||||||
|
if (csv == nullptr)
|
||||||
|
{
|
||||||
|
std::perror("bench_decode.csv");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::fprintf(csv, "doc,bytes,engine,ns\n");
|
||||||
|
for (const auto& c : cases)
|
||||||
|
{
|
||||||
|
// all engines must decode the same values
|
||||||
|
const std::size_t expected = c.engines[0].run();
|
||||||
|
bool ok = true;
|
||||||
|
for (const auto& e : c.engines)
|
||||||
|
{
|
||||||
|
ok = ok && e.run() == expected;
|
||||||
|
}
|
||||||
|
std::vector<double> best(c.engines.size(), 1e300);
|
||||||
|
for (int r = 0; r < rounds; ++r)
|
||||||
|
{
|
||||||
|
for (std::size_t k = 0; k < c.engines.size(); ++k)
|
||||||
|
{
|
||||||
|
g_sink = c.engines[k].run(); // untimed: see bench_view.cpp
|
||||||
|
best[k] = std::min(best[k], time_ns([&] { g_sink = c.engines[k].run(); }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::printf("%-13s %-7s %s", c.name.c_str(), "decode", ok ? "" : "[MISMATCH] ");
|
||||||
|
for (std::size_t k = 0; k < c.engines.size(); ++k)
|
||||||
|
{
|
||||||
|
const double us = best[k] / 1000.0;
|
||||||
|
std::printf(" %s %.*fus (%.2fx)", c.engines[k].name.c_str(), us < 10 ? 3 : (us < 1000 ? 1 : 0), us, best[k] / best[0]);
|
||||||
|
std::fprintf(csv, "%s,%zu,%s,%.1f\n", c.name.c_str(), c.text.size(), c.engines[k].name.c_str(), best[k]);
|
||||||
|
}
|
||||||
|
std::printf("\n");
|
||||||
|
}
|
||||||
|
std::fclose(csv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
"""Compare json_view with yyjson, simdjson, Boost.JSON, and json::parse.
|
"""Compare json_view with yyjson, simdjson, Boost.JSON, and json::parse.
|
||||||
|
|
||||||
Builds bench_view.cpp, bench_corpus.cpp, and bench_edit.cpp against the include/ directory of
|
Builds bench_view.cpp, bench_corpus.cpp, bench_edit.cpp, and bench_decode.cpp against the include/ directory of
|
||||||
this checkout, runs them, and writes the results with everything needed to
|
this checkout, runs them, and writes the results with everything needed to
|
||||||
reproduce them (date, commit, CPU, OS, compiler, library versions, flags) to
|
reproduce them (date, commit, CPU, OS, compiler, library versions, flags) to
|
||||||
results/<date>-<host>.md and .csv next to this script.
|
results/<date>-<host>.md and .csv next to this script.
|
||||||
@@ -283,7 +283,7 @@ def main():
|
|||||||
objects.append(obj)
|
objects.append(obj)
|
||||||
|
|
||||||
binaries = {}
|
binaries = {}
|
||||||
for bench in ['bench_view', 'bench_corpus', 'bench_edit']:
|
for bench in ['bench_view', 'bench_corpus', 'bench_edit', 'bench_decode']:
|
||||||
exe = os.path.join(args.build_dir, bench)
|
exe = os.path.join(args.build_dir, bench)
|
||||||
run(cxx + flags + include + [os.path.join(HERE, bench + '.cpp')] + objects + link + ['-o', exe])
|
run(cxx + flags + include + [os.path.join(HERE, bench + '.cpp')] + objects + link + ['-o', exe])
|
||||||
binaries[bench] = exe
|
binaries[bench] = exe
|
||||||
@@ -297,6 +297,8 @@ def main():
|
|||||||
capture_output=True, text=True).stdout
|
capture_output=True, text=True).stdout
|
||||||
outputs['bench_edit'] = run([binaries['bench_edit'], args.data, str(max(1, args.rounds // 2))], cwd=args.build_dir,
|
outputs['bench_edit'] = run([binaries['bench_edit'], args.data, str(max(1, args.rounds // 2))], cwd=args.build_dir,
|
||||||
capture_output=True, text=True).stdout
|
capture_output=True, text=True).stdout
|
||||||
|
outputs['bench_decode'] = run([binaries['bench_decode'], args.data, str(max(1, args.rounds // 2))], cwd=args.build_dir,
|
||||||
|
capture_output=True, text=True).stdout
|
||||||
for name, text in outputs.items():
|
for name, text in outputs.items():
|
||||||
print(text)
|
print(text)
|
||||||
|
|
||||||
@@ -330,7 +332,7 @@ def main():
|
|||||||
f.write(f'\n## {name}\n\n```\n{text.rstrip()}\n```\n')
|
f.write(f'\n## {name}\n\n```\n{text.rstrip()}\n```\n')
|
||||||
with open(stem + '.csv', 'w', encoding='utf-8') as out:
|
with open(stem + '.csv', 'w', encoding='utf-8') as out:
|
||||||
out.write(''.join(f'# {key}: {value}\n' for key, value in meta))
|
out.write(''.join(f'# {key}: {value}\n' for key, value in meta))
|
||||||
for name in ['bench_view', 'bench_corpus', 'bench_edit']:
|
for name in ['bench_view', 'bench_corpus', 'bench_edit', 'bench_decode']:
|
||||||
path = os.path.join(args.build_dir, name + '.csv')
|
path = os.path.join(args.build_dir, name + '.csv')
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
with open(path, encoding='utf-8') as f:
|
with open(path, encoding='utf-8') as f:
|
||||||
|
|||||||
@@ -0,0 +1,357 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
using nlohmann::json;
|
||||||
|
using nlohmann::json_document;
|
||||||
|
using nlohmann::json_view;
|
||||||
|
using nlohmann::json_editable_document;
|
||||||
|
using nlohmann::ordered_json_document;
|
||||||
|
|
||||||
|
#include "json_view_test_helpers.hpp"
|
||||||
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
|
using json_view_test::exception_of_call;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <deque>
|
||||||
|
#include <forward_list>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <utility>
|
||||||
|
#include <valarray>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef JSON_HAS_CPP_17
|
||||||
|
#include <optional>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The from_json() functions of the NLOHMANN_DEFINE_TYPE_* and
|
||||||
|
// NLOHMANN_JSON_SERIALIZE_ENUM macros read views directly; other from_json()
|
||||||
|
// functions get the value of materialize().
|
||||||
|
|
||||||
|
namespace view_from_json
|
||||||
|
{
|
||||||
|
struct point
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(point, x, y)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct shape
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::vector<point> points;
|
||||||
|
point center;
|
||||||
|
std::map<std::string, point> named;
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(shape, name, points, center, named)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct with_defaults
|
||||||
|
{
|
||||||
|
int a = 1;
|
||||||
|
std::string b = "default";
|
||||||
|
std::vector<int> c = {1, 2};
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(with_defaults, a, b, c)
|
||||||
|
|
||||||
|
struct with_names
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
std::string text;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(with_names, "Value", value, "Text", text)
|
||||||
|
|
||||||
|
struct empty
|
||||||
|
{
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(empty)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class color
|
||||||
|
{
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue
|
||||||
|
};
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(color,
|
||||||
|
{
|
||||||
|
{color::red, "red"},
|
||||||
|
{color::green, "green"},
|
||||||
|
{color::blue, nullptr},
|
||||||
|
})
|
||||||
|
|
||||||
|
enum class strict_color
|
||||||
|
{
|
||||||
|
red,
|
||||||
|
green
|
||||||
|
};
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(strict_color,
|
||||||
|
{
|
||||||
|
{strict_color::red, "red"},
|
||||||
|
{strict_color::green, 1},
|
||||||
|
})
|
||||||
|
|
||||||
|
struct base
|
||||||
|
{
|
||||||
|
int id = 0;
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(base, id)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct derived : base
|
||||||
|
{
|
||||||
|
color c = color::red;
|
||||||
|
NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived, base, c)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct derived_with_defaults : base
|
||||||
|
{
|
||||||
|
std::string label = "none";
|
||||||
|
NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(derived_with_defaults, base, label)
|
||||||
|
};
|
||||||
|
|
||||||
|
// a base whose from_json() is written for json only: the derived type reads
|
||||||
|
// its own members from the view and the base part from materialize()
|
||||||
|
struct legacy_base
|
||||||
|
{
|
||||||
|
int id = 0;
|
||||||
|
};
|
||||||
|
// NOLINTNEXTLINE(misc-use-internal-linkage): found by ADL, like the from_json() functions of users
|
||||||
|
inline void from_json(const json& j, legacy_base& b)
|
||||||
|
{
|
||||||
|
b.id = j.at("id").get<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct derived_from_legacy : legacy_base
|
||||||
|
{
|
||||||
|
int extra = 0;
|
||||||
|
};
|
||||||
|
NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(derived_from_legacy, legacy_base, extra)
|
||||||
|
|
||||||
|
// from_json() for json only: converted through materialize()
|
||||||
|
struct legacy
|
||||||
|
{
|
||||||
|
int v = 0;
|
||||||
|
};
|
||||||
|
// NOLINTNEXTLINE(misc-use-internal-linkage): found by ADL, like the from_json() functions of users
|
||||||
|
inline void from_json(const json& j, legacy& l)
|
||||||
|
{
|
||||||
|
l.v = j.at("v").get<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// an unconstrained from_json() template, as in the documentation of
|
||||||
|
// arbitrary type conversions: converted through materialize()
|
||||||
|
struct unconstrained
|
||||||
|
{
|
||||||
|
int v = 0;
|
||||||
|
};
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
// NOLINTNEXTLINE(misc-use-internal-linkage): found by ADL, like the from_json() functions of users
|
||||||
|
void from_json(const BasicJsonType& j, unconstrained& u)
|
||||||
|
{
|
||||||
|
u.v = j.at("v").template get<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// a from_json() constrained by the user to views and json: reads the view
|
||||||
|
struct constrained
|
||||||
|
{
|
||||||
|
int v = 0;
|
||||||
|
};
|
||||||
|
template < typename J, typename std::enable_if < nlohmann::is_json_view<J>::value || std::is_same<J, json>::value, int >::type = 0 >
|
||||||
|
// NOLINTNEXTLINE(misc-use-internal-linkage): found by ADL, like the from_json() functions of users
|
||||||
|
void from_json(const J& j, constrained& c)
|
||||||
|
{
|
||||||
|
c.v = j.at("v").template get<int>();
|
||||||
|
}
|
||||||
|
} // namespace view_from_json
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template<typename T, typename View = json_view>
|
||||||
|
struct reads_view : nlohmann::detail::has_view_from_json<nlohmann::adl_serializer<T, void>, View, T> {};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("json_view from_json")
|
||||||
|
{
|
||||||
|
using namespace view_from_json; // NOLINT(google-build-using-namespace)
|
||||||
|
|
||||||
|
SECTION("which from_json() functions read views")
|
||||||
|
{
|
||||||
|
static_assert(reads_view<point>::value, "macro types read views");
|
||||||
|
static_assert(reads_view<shape>::value, "macro types read views");
|
||||||
|
static_assert(reads_view<with_defaults>::value, "macro types read views");
|
||||||
|
static_assert(reads_view<with_names>::value, "macro types read views");
|
||||||
|
static_assert(reads_view<empty>::value, "macro types read views");
|
||||||
|
static_assert(reads_view<derived>::value, "macro types read views");
|
||||||
|
static_assert(reads_view<derived_from_legacy>::value, "macro types read views");
|
||||||
|
static_assert(reads_view<color>::value, "enum macro types read views");
|
||||||
|
static_assert(reads_view<strict_color>::value, "enum macro types read views");
|
||||||
|
static_assert(reads_view<constrained>::value, "constrained from_json() reads views");
|
||||||
|
static_assert(reads_view<point, nlohmann::json_editable_view>::value, "editable views as well");
|
||||||
|
static_assert(reads_view<point, nlohmann::ordered_json_view>::value, "views of ordered_json as well");
|
||||||
|
static_assert(!reads_view<legacy>::value, "from_json() for json");
|
||||||
|
static_assert(!reads_view<legacy_base>::value, "from_json() for json");
|
||||||
|
static_assert(!reads_view<unconstrained>::value, "unconstrained from_json()");
|
||||||
|
|
||||||
|
static_assert(nlohmann::is_json_view<json_view>::value, "is_json_view");
|
||||||
|
static_assert(nlohmann::is_json_view<nlohmann::ordered_json_editable_view>::value, "is_json_view");
|
||||||
|
static_assert(!nlohmann::is_json_view<json>::value, "is_json_view");
|
||||||
|
static_assert(!nlohmann::is_json_view<json_document>::value, "is_json_view");
|
||||||
|
static_assert(!nlohmann::is_json_view<int>::value, "is_json_view");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("the library's own conversions are not called with a view (and the probe compiles for them)")
|
||||||
|
{
|
||||||
|
// these go through materialize() (vectors, maps with string keys,
|
||||||
|
// strings, and numbers are converted by the view itself)
|
||||||
|
static_assert(!reads_view<std::list<int>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::deque<point>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::set<std::string>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::unordered_set<int>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::forward_list<int>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::valarray<double>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::array<int, 3>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::pair<int, std::string>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::tuple<int, bool, point>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::map<int, int>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::unordered_map<int, point>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::map<color, int>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::map<std::string, int>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::vector<point>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::vector<bool>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::vector<std::uint8_t>>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::string>::value, "std types");
|
||||||
|
static_assert(!reads_view<int>::value, "std types");
|
||||||
|
static_assert(!reads_view<bool>::value, "std types");
|
||||||
|
static_assert(!reads_view<double>::value, "std types");
|
||||||
|
static_assert(!reads_view<std::nullptr_t>::value, "std types");
|
||||||
|
static_assert(!reads_view<json>::value, "std types");
|
||||||
|
static_assert(!reads_view<json::binary_t>::value, "std types");
|
||||||
|
#ifdef JSON_HAS_CPP_17
|
||||||
|
static_assert(!reads_view<std::optional<point>>::value, "std types");
|
||||||
|
#endif
|
||||||
|
CHECK(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("macro types")
|
||||||
|
{
|
||||||
|
const json_document d = json_document::parse(R"({"name": "s", "points": [{"x": 1, "y": 2}, {"x": 3, "y": 4}],
|
||||||
|
"center": {"x": 5, "y": 6}, "named": {"a": {"x": 7, "y": 8}}})");
|
||||||
|
const shape s = d.root().get<shape>();
|
||||||
|
CHECK(s.name == "s");
|
||||||
|
CHECK(s.points.size() == 2);
|
||||||
|
CHECK(s.points[1].y == 4);
|
||||||
|
CHECK(s.center.x == 5);
|
||||||
|
CHECK(s.named.at("a").y == 8);
|
||||||
|
|
||||||
|
point p;
|
||||||
|
d.root()["center"].get_to(p);
|
||||||
|
CHECK(p.x == 5);
|
||||||
|
CHECK(p.y == 6);
|
||||||
|
|
||||||
|
static_cast<void>(d.root()["center"].get<empty>());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("defaults and names")
|
||||||
|
{
|
||||||
|
const json_document d = json_document::parse(R"({"a": 5, "Value": 3, "Text": "t"})");
|
||||||
|
const with_defaults w = d.root().get<with_defaults>();
|
||||||
|
CHECK(w.a == 5);
|
||||||
|
CHECK(w.b == "default");
|
||||||
|
CHECK(w.c == std::vector<int> {1, 2});
|
||||||
|
const json_document null_document = json_document::parse("null");
|
||||||
|
CHECK(null_document.root().get<with_defaults>().a == 1);
|
||||||
|
const with_names n = d.root().get<with_names>();
|
||||||
|
CHECK(n.value == 3);
|
||||||
|
CHECK(n.text == "t");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("enums")
|
||||||
|
{
|
||||||
|
const json_document d = json_document::parse(R"(["green", null, "purple", 1, "red"])");
|
||||||
|
CHECK(d.root()[0].get<color>() == color::green);
|
||||||
|
CHECK(d.root()[1].get<color>() == color::blue);
|
||||||
|
CHECK(d.root()[2].get<color>() == color::red); // unknown values map to the first entry
|
||||||
|
CHECK(d.root()[3].get<strict_color>() == strict_color::green);
|
||||||
|
CHECK(d.root()[4].get<strict_color>() == strict_color::red);
|
||||||
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
|
const json j = d.root().materialize();
|
||||||
|
CHECK(exception_of_call([&] { static_cast<void>(d.root()[2].get<strict_color>()); }) == "[json.exception.out_of_range.410] enum value out of range for strict_color: \"purple\"");
|
||||||
|
#if !JSON_DIAGNOSTICS
|
||||||
|
CHECK(exception_of_call([&] { static_cast<void>(d.root()[2].get<strict_color>()); }) == exception_of_call([&] { static_cast<void>(j[2].get<strict_color>()); }));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("derived types")
|
||||||
|
{
|
||||||
|
const json_document d = json_document::parse(R"({"id": 7, "c": "green", "extra": 3})");
|
||||||
|
const derived x = d.root().get<derived>();
|
||||||
|
CHECK(x.id == 7);
|
||||||
|
CHECK(x.c == color::green);
|
||||||
|
const derived_with_defaults y = d.root().get<derived_with_defaults>();
|
||||||
|
CHECK(y.id == 7);
|
||||||
|
CHECK(y.label == "none");
|
||||||
|
const derived_from_legacy z = d.root().get<derived_from_legacy>();
|
||||||
|
CHECK(z.id == 7);
|
||||||
|
CHECK(z.extra == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("other from_json() functions get the value of materialize()")
|
||||||
|
{
|
||||||
|
const json_document d = json_document::parse(R"({"v": 4})");
|
||||||
|
CHECK(d.root().get<legacy>().v == 4);
|
||||||
|
CHECK(d.root().get<unconstrained>().v == 4);
|
||||||
|
CHECK(d.root().get<constrained>().v == 4);
|
||||||
|
legacy l;
|
||||||
|
d.root().get_to(l);
|
||||||
|
CHECK(l.v == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("duplicate keys: members are looked up in the view, where the first one wins")
|
||||||
|
{
|
||||||
|
const json_document d = json_document::parse(R"({"x": 1, "y": 2, "x": 3})");
|
||||||
|
CHECK(d.root().get<point>().x == 1);
|
||||||
|
// materialize() keeps the last value, like parse()
|
||||||
|
CHECK(d.root().materialize().get<point>().x == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("editable documents and ordered_json")
|
||||||
|
{
|
||||||
|
json_editable_document e = json_editable_document::parse(R"({"x": 1, "y": 2})");
|
||||||
|
e.set(e.root(), "x", 10);
|
||||||
|
CHECK(e.root().get<point>().x == 10);
|
||||||
|
const ordered_json_document o = ordered_json_document::parse(R"({"name": "o", "points": [], "center": {"x": 1, "y": 2}, "named": {}})");
|
||||||
|
CHECK(o.root().get<shape>().center.y == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(JSON_NOEXCEPTION) && !JSON_DIAGNOSTICS
|
||||||
|
SECTION("errors are those of the same conversion of a json value")
|
||||||
|
{
|
||||||
|
// (with JSON_DIAGNOSTICS, those of json name the path of the value)
|
||||||
|
const json_document d = json_document::parse(R"([{"x": 1}, {"x": "1", "y": 2}, [1, 2], {"id": "7", "c": "red"}])");
|
||||||
|
const json j = d.root().materialize();
|
||||||
|
for (std::size_t i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
CAPTURE(i)
|
||||||
|
CHECK(exception_of_call([&] { static_cast<void>(d.root()[i].get<point>()); }) == exception_of_call([&] { static_cast<void>(j[i].get<point>()); }));
|
||||||
|
}
|
||||||
|
CHECK(exception_of_call([&] { static_cast<void>(d.root()[3].get<derived>()); }) == exception_of_call([&] { static_cast<void>(j[3].get<derived>()); }));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -28,11 +28,25 @@ using nlohmann::detail::view::node;
|
|||||||
#include <random>
|
#include <random>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
|
||||||
|
namespace json_view_image_test
|
||||||
|
{
|
||||||
|
// whether a document type has save() and load() (only on little-endian targets)
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct has_save : std::false_type {};
|
||||||
|
template<typename T>
|
||||||
|
struct has_save<T, decltype(static_cast<void>(std::declval<const T&>().save()))> : std::true_type {};
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct has_load : std::false_type {};
|
||||||
|
template<typename T>
|
||||||
|
struct has_load<T, decltype(static_cast<void>(T::load(std::declval<const std::vector<std::uint8_t>&>())))> : std::true_type {};
|
||||||
|
} // namespace json_view_image_test
|
||||||
|
|
||||||
#if !(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
#if !(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -171,6 +185,9 @@ std::uint32_t rng()
|
|||||||
|
|
||||||
TEST_CASE("json_view images: round trips")
|
TEST_CASE("json_view images: round trips")
|
||||||
{
|
{
|
||||||
|
static_assert(json_view_image_test::has_save<json_document>::value && json_view_image_test::has_load<json_document>::value, "save() and load() on a little-endian target");
|
||||||
|
static_assert(json_view_image_test::has_save<ordered_json_editable_document>::value && json_view_image_test::has_load<ordered_json_editable_document>::value, "save() and load() on a little-endian target");
|
||||||
|
|
||||||
SECTION("small documents")
|
SECTION("small documents")
|
||||||
{
|
{
|
||||||
for (const char* text :
|
for (const char* text :
|
||||||
@@ -1275,8 +1292,12 @@ TEST_CASE("json_view images: damaged images")
|
|||||||
|
|
||||||
TEST_CASE("json_view images: big-endian targets")
|
TEST_CASE("json_view images: big-endian targets")
|
||||||
{
|
{
|
||||||
|
// the image format is little-endian: save() and load() do not exist here
|
||||||
|
static_assert(!json_view_image_test::has_save<json_document>::value, "no save() on a big-endian target");
|
||||||
|
static_assert(!json_view_image_test::has_load<json_document>::value, "no load() on a big-endian target");
|
||||||
|
static_assert(!json_view_image_test::has_save<json_editable_document>::value, "no save() on a big-endian target");
|
||||||
const json_document d = json_document::parse("[1]");
|
const json_document d = json_document::parse("[1]");
|
||||||
CHECK_THROWS_WITH_AS(d.save(), "[json.exception.type_error.320] json_document images need a little-endian target", json::type_error&);
|
CHECK(d.root().size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -34,11 +34,11 @@ version other than the one in `abi_macros.hpp`.
|
|||||||
| Option | Description |
|
| Option | Description |
|
||||||
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `--list-tags` | Print every ABI tag (in namespace order) with the macro that enables it and the `NLOHMANN_JSON_ABI_TAG_*` identifier, then exit. |
|
| `--list-tags` | Print every ABI tag (in namespace order) with the macro that enables it and the `NLOHMANN_JSON_ABI_TAG_*` identifier, then exit. |
|
||||||
| `--abi-tags TAGS` | Add the namespaces of one configuration, given as a comma-separated list of ABI tags (`_diag,_dp,_vns`; the leading underscore is optional, and the order does not matter). Can be repeated for several configurations. Unknown tags are an error. |
|
| `--abi-tags TAGS` | Add the namespaces of one configuration, given as a comma-separated list of ABI tags (`_diag,_dp,_ns`; the leading underscore is optional, and the order does not matter). Can be repeated for several configurations. Unknown tags are an error. |
|
||||||
| `--all` | Generate the namespaces for every combination of ABI tags. The file size doubles with each tag (about 60 MB for 12 tags). Cannot be combined with `--abi-tags`. |
|
| `--all` | Generate the namespaces for every combination of ABI tags. The file size doubles with each tag (about 60 MB for 12 tags). Cannot be combined with `--abi-tags`. |
|
||||||
| `--output FILE` | Write the Natvis file to `FILE` instead of `nlohmann_json.natvis` in the repository root. |
|
| `--output FILE` | Write the Natvis file to `FILE` instead of `nlohmann_json.natvis` in the repository root. |
|
||||||
|
|
||||||
Each configuration gets both the versioned (`json_abi_diag_dp_vns_v3_12_0`) and the unversioned (`json_abi_diag_dp_vns`,
|
Each configuration gets both the versioned (`json_abi_diag_dp_ns_v3_12_0`) and the unversioned (`json_abi_diag_dp_ns`,
|
||||||
used with `NLOHMANN_JSON_NAMESPACE_NO_VERSION`) namespace. The default namespaces (up to two ABI tags) are always
|
used with `NLOHMANN_JSON_NAMESPACE_NO_VERSION`) namespace. The default namespaces (up to two ABI tags) are always
|
||||||
included, so a generated file can replace the checked-in one.
|
included, so a generated file can replace the checked-in one.
|
||||||
|
|
||||||
@@ -52,10 +52,10 @@ included, so a generated file can replace the checked-in one.
|
|||||||
```
|
```
|
||||||
|
|
||||||
3. Generate a Natvis file with them, for example for `JSON_DIAGNOSTICS`, `JSON_DIAGNOSTIC_POSITIONS`, and
|
3. Generate a Natvis file with them, for example for `JSON_DIAGNOSTICS`, `JSON_DIAGNOSTIC_POSITIONS`, and
|
||||||
`JSON_VIEW_NO_SIMD`:
|
`JSON_NO_SIMD`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my_nlohmann_json.natvis"
|
make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_ns --output my_nlohmann_json.natvis"
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Use `my_nlohmann_json.natvis` instead of the shipped `nlohmann_json.natvis`, for example by adding it to your Visual
|
4. Use `my_nlohmann_json.natvis` instead of the shipped `nlohmann_json.natvis`, for example by adding it to your Visual
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ if __name__ == '__main__':
|
|||||||
'include/nlohmann/detail/abi_macros.hpp below "repo_root")')
|
'include/nlohmann/detail/abi_macros.hpp below "repo_root")')
|
||||||
selection = parser.add_mutually_exclusive_group()
|
selection = parser.add_mutually_exclusive_group()
|
||||||
selection.add_argument('--abi-tags', action='append', default=[], metavar='TAGS',
|
selection.add_argument('--abi-tags', action='append', default=[], metavar='TAGS',
|
||||||
help='Comma-separated list of ABI tags (e.g. "_diag,_dp,_vns", leading underscores are '
|
help='Comma-separated list of ABI tags (e.g. "_diag,_dp,_ns", leading underscores are '
|
||||||
'optional) of one configuration to add to the default namespaces; can be repeated')
|
'optional) of one configuration to add to the default namespaces; can be repeated')
|
||||||
selection.add_argument('--all', action='store_true',
|
selection.add_argument('--all', action='store_true',
|
||||||
help='Generate the namespaces for every combination of ABI tags; the file size doubles '
|
help='Generate the namespaces for every combination of ABI tags; the file size doubles '
|
||||||
|
|||||||
Reference in new issue
Block a user