mirror of
https://github.com/nlohmann/json.git
synced 2026-10-05 14:10:31 +00:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f086dec2b | ||
|
|
336c808485 | ||
|
|
556027f109 | ||
|
|
413dd2d2c9 | ||
|
|
98eff63537 | ||
|
|
f88e209ea9 | ||
|
|
d5a1c5d149 | ||
|
|
23d3b373e1 | ||
|
|
c5a7a4b46d | ||
|
|
4f69be80d6 | ||
|
|
8c1f60a45e | ||
|
|
6b4b825af2 |
@@ -107,7 +107,7 @@ jobs:
|
|||||||
container: ubuntu:24.04
|
container: ubuntu:24.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_no_thread_local]
|
target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_delete_deprecated_functions, ci_test_no_thread_local]
|
||||||
steps:
|
steps:
|
||||||
- name: Install build-essential
|
- name: Install build-essential
|
||||||
run: apt-get update ; apt-get install -y build-essential unzip wget git
|
run: apt-get update ; apt-get install -y build-essential unzip wget git
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ option(JSON_MultipleHeaders "Use non-amalgamated version of the l
|
|||||||
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
|
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
|
||||||
option(JSON_StrictNulHandling "Build with strict NUL-byte handling enabled." OFF)
|
option(JSON_StrictNulHandling "Build with strict NUL-byte handling enabled." OFF)
|
||||||
option(JSON_StrictBinaryUTF8 "Build with UTF-8 checks in the CBOR, UBJSON, BJData, and BSON writers enabled." OFF)
|
option(JSON_StrictBinaryUTF8 "Build with UTF-8 checks in the CBOR, UBJSON, BJData, and BSON writers enabled." OFF)
|
||||||
|
option(JSON_DeleteDeprecatedFunctions "Delete the deprecated functions instead of only deprecating them." OFF)
|
||||||
|
|
||||||
if (JSON_CI)
|
if (JSON_CI)
|
||||||
include(ci)
|
include(ci)
|
||||||
@@ -123,6 +124,10 @@ if (JSON_StrictBinaryUTF8)
|
|||||||
message(STATUS "Strict UTF-8 checks in binary writers enabled (JSON_STRICT_BINARY_UTF8=1)")
|
message(STATUS "Strict UTF-8 checks in binary writers enabled (JSON_STRICT_BINARY_UTF8=1)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (JSON_DeleteDeprecatedFunctions)
|
||||||
|
message(STATUS "Deprecated functions are deleted (JSON_DELETE_DEPRECATED_FUNCTIONS=1)")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (JSON_Diagnostic_Positions)
|
if (JSON_Diagnostic_Positions)
|
||||||
message(STATUS "Diagnostic positions enabled (JSON_DIAGNOSTIC_POSITIONS=1)")
|
message(STATUS "Diagnostic positions enabled (JSON_DIAGNOSTIC_POSITIONS=1)")
|
||||||
endif()
|
endif()
|
||||||
@@ -159,6 +164,7 @@ target_compile_definitions(
|
|||||||
$<$<BOOL:${JSON_LegacyDiscardedValueComparison}>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>
|
$<$<BOOL:${JSON_LegacyDiscardedValueComparison}>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>
|
||||||
$<$<BOOL:${JSON_StrictNulHandling}>:JSON_STRICT_NUL_HANDLING=1>
|
$<$<BOOL:${JSON_StrictNulHandling}>:JSON_STRICT_NUL_HANDLING=1>
|
||||||
$<$<BOOL:${JSON_StrictBinaryUTF8}>:JSON_STRICT_BINARY_UTF8=1>
|
$<$<BOOL:${JSON_StrictBinaryUTF8}>:JSON_STRICT_BINARY_UTF8=1>
|
||||||
|
$<$<BOOL:${JSON_DeleteDeprecatedFunctions}>:JSON_DELETE_DEPRECATED_FUNCTIONS=1>
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
|
|||||||
+16
-2
@@ -249,6 +249,20 @@ add_custom_target(ci_test_strict_nul_handling
|
|||||||
COMMENT "Compile and test with strict NUL-byte handling enabled"
|
COMMENT "Compile and test with strict NUL-byte handling enabled"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Delete the deprecated functions.
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
add_custom_target(ci_test_delete_deprecated_functions
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
||||||
|
-DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_DeleteDeprecatedFunctions=ON
|
||||||
|
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_delete_deprecated_functions
|
||||||
|
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_delete_deprecated_functions
|
||||||
|
COMMAND cd ${PROJECT_BINARY_DIR}/build_delete_deprecated_functions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
|
||||||
|
COMMENT "Compile and test with the deprecated functions deleted"
|
||||||
|
)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Disable global UDLs.
|
# Disable global UDLs.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -362,7 +376,7 @@ add_custom_target(ci_test_coverage
|
|||||||
# Sanitizers.
|
# Sanitizers.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base")
|
set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base -fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/cmake/clang_sanitizer_ignorelist.txt")
|
||||||
|
|
||||||
add_custom_target(ci_test_clang_sanitizer
|
add_custom_target(ci_test_clang_sanitizer
|
||||||
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND}
|
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND}
|
||||||
@@ -705,7 +719,7 @@ ci_get_cmake(4.0.0 CMAKE_4_0_0_BINARY)
|
|||||||
# the tests require CMake 3.13 or later, so they are excluded for CMake 3.5.0
|
# the tests require CMake 3.13 or later, so they are excluded for CMake 3.5.0
|
||||||
set(JSON_CMAKE_FLAGS_3_5_0 JSON_Diagnostics JSON_Diagnostic_Positions JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization
|
set(JSON_CMAKE_FLAGS_3_5_0 JSON_Diagnostics JSON_Diagnostic_Positions JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization
|
||||||
JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind
|
JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind
|
||||||
JSON_StrictNulHandling JSON_StrictBinaryUTF8)
|
JSON_StrictNulHandling JSON_StrictBinaryUTF8 JSON_DeleteDeprecatedFunctions)
|
||||||
set(JSON_CMAKE_FLAGS_3_31_6 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
set(JSON_CMAKE_FLAGS_3_31_6 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
||||||
set(JSON_CMAKE_FLAGS_4_0_0 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
set(JSON_CMAKE_FLAGS_4_0_0 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Sanitizer ignore list for ci_test_clang_sanitizer (-fsanitize-ignorelist).
|
||||||
|
#
|
||||||
|
# libstdc++ 14's <format> declares `_Scanner(basic_string_view<_CharT>, size_t __nargs = -1)`, so every std::format
|
||||||
|
# call converts -1 to size_t, which -fsanitize=integer reports as implicit-integer-sign-change. This is
|
||||||
|
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119429, not a bug in this library. Only that check and only <format> are
|
||||||
|
# excluded, so implicit sign changes in the library and the tests are still reported.
|
||||||
|
[implicit-integer-sign-change]
|
||||||
|
src:*/include/c++/*/format
|
||||||
@@ -219,6 +219,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('Supported Macros', 'Guide', '
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'api/macros/json_assert/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'api/macros/json_assert/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_BRACE_INIT_COPY_SEMANTICS', 'Macro', 'api/macros/json_brace_init_copy_semantics/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_BRACE_INIT_COPY_SEMANTICS', 'Macro', 'api/macros/json_brace_init_copy_semantics/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'api/macros/json_throw_user/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'api/macros/json_throw_user/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DELETE_DEPRECATED_FUNCTIONS', 'Macro', 'api/macros/json_delete_deprecated_functions/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'api/macros/json_diagnostics/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'api/macros/json_diagnostics/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTIC_POSITIONS', 'Macro', 'api/macros/json_diagnostic_positions/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTIC_POSITIONS', 'Macro', 'api/macros/json_diagnostic_positions/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'api/macros/json_disable_enum_serialization/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'api/macros/json_disable_enum_serialization/index.html');
|
||||||
@@ -249,6 +250,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('JSON_TRY_USER', 'Macro', 'api
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_GLOBAL_UDLS', 'Macro', 'api/macros/json_use_global_udls/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_GLOBAL_UDLS', 'Macro', 'api/macros/json_use_global_udls/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'api/macros/json_use_implicit_conversions/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'api/macros/json_use_implicit_conversions/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON', 'Macro', 'api/macros/json_use_legacy_discarded_value_comparison/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON', 'Macro', 'api/macros/json_use_legacy_discarded_value_comparison/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS', 'Macro', 'api/macros/json_use_objects_for_enum_keyed_maps/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_SIMDUTF', 'Macro', 'api/macros/json_use_simdutf/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_SIMDUTF', 'Macro', 'api/macros/json_use_simdutf/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('Macros', 'Macro', 'api/macros/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('Macros', 'Macro', 'api/macros/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ static basic_json diff(const basic_json& source,
|
|||||||
Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling
|
Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling
|
||||||
[`patch`](patch.md) function.
|
[`patch`](patch.md) function.
|
||||||
|
|
||||||
For two JSON values `source` and `target`, the following code yields always `#!cpp true`:
|
For two JSON values `source` and `target`, the following code always yields `#!cpp true`:
|
||||||
```cpp
|
```cpp
|
||||||
source.patch(diff(source, target)) == target;
|
source.patch(diff(source, target)) == target;
|
||||||
```
|
```
|
||||||
@@ -27,7 +27,7 @@ a JSON patch to convert the `source` to `target`
|
|||||||
|
|
||||||
## Exception safety
|
## Exception safety
|
||||||
|
|
||||||
Strong guarantee: if an exception is thrown, there are no changes in the JSON value.
|
Strong guarantee: `source` and `target` are never modified.
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
|
|||||||
@@ -120,3 +120,12 @@ Linear in the size of the input.
|
|||||||
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
|
||||||
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
|
||||||
- Added `error_handler` parameter in version 3.13.0.
|
- Added `error_handler` parameter in version 3.13.0.
|
||||||
|
|
||||||
|
!!! warning "Deprecation"
|
||||||
|
|
||||||
|
- Overload (2) replaces calls to `from_bjdata` with a pointer and a length as first two parameters, which has been
|
||||||
|
deprecated in version 3.13.0. This overload will be removed in version 4.0.0. Please replace all calls like
|
||||||
|
`#!cpp from_bjdata(ptr, len, ...);` with `#!cpp from_bjdata(ptr, ptr+len, ...);`.
|
||||||
|
|
||||||
|
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
|
||||||
|
function.
|
||||||
|
|||||||
@@ -106,3 +106,12 @@ Linear in the size of the input.
|
|||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
- Added in version 3.13.0.
|
||||||
|
|
||||||
|
!!! warning "Deprecation"
|
||||||
|
|
||||||
|
- Overload (2) replaces calls to `from_bon8` with a pointer and a length as first two parameters, which has been
|
||||||
|
deprecated in version 3.13.0. This overload will be removed in version 4.0.0. Please replace all calls like
|
||||||
|
`#!cpp from_bon8(ptr, len, ...);` with `#!cpp from_bon8(ptr, ptr+len, ...);`.
|
||||||
|
|
||||||
|
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
|
||||||
|
function.
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ This implementation does exactly follow this approach, as it uses double precisi
|
|||||||
smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally
|
smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally
|
||||||
and be serialized to `null`.
|
and be serialized to `null`.
|
||||||
|
|
||||||
|
During deserialization (from JSON text or any of the binary formats), a finite number that does not fit into
|
||||||
|
`number_float_t` is rejected with [`out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406), for
|
||||||
|
example a double-precision number in a binary format when `number_float_t` is `#!cpp float`.
|
||||||
|
|
||||||
### Storage
|
### Storage
|
||||||
|
|
||||||
Floating-point number values are stored directly inside a `basic_json` type.
|
Floating-point number values are stored directly inside a `basic_json` type.
|
||||||
|
|||||||
@@ -47,8 +47,9 @@ With the default values for `NumberIntegerType` (`std::int64_t`), the default va
|
|||||||
|
|
||||||
When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and
|
When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and
|
||||||
the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of
|
the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of
|
||||||
range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers
|
range will yield over/underflow when used in a constructor. During deserialization (from JSON text or any of the binary
|
||||||
will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md).
|
formats), too large or small integer numbers will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md)
|
||||||
|
or [`number_float_t`](number_float_t.md).
|
||||||
|
|
||||||
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
||||||
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ With the default values for `NumberUnsignedType` (`std::uint64_t`), the default
|
|||||||
|
|
||||||
When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and
|
When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and
|
||||||
the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow
|
the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow
|
||||||
when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored
|
when used in a constructor. During deserialization (from JSON text or any of the binary formats), too large or small
|
||||||
as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md).
|
integer numbers will automatically be stored as [`number_integer_t`](number_integer_t.md) or
|
||||||
|
[`number_float_t`](number_float_t.md).
|
||||||
|
|
||||||
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
|
||||||
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
|
||||||
|
|||||||
@@ -58,6 +58,13 @@ header. See also the [macro overview page](../../features/macros.md).
|
|||||||
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums
|
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums
|
||||||
- [**JSON_DISABLE_TUPLE_REFERENCE_CONVERSION**](json_disable_tuple_reference_conversion.md) - switch off conversion from a one-element tuple of a JSON reference
|
- [**JSON_DISABLE_TUPLE_REFERENCE_CONVERSION**](json_disable_tuple_reference_conversion.md) - switch off conversion from a one-element tuple of a JSON reference
|
||||||
- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions
|
- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions
|
||||||
|
- [**JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS**](json_use_objects_for_enum_keyed_maps.md) - opt in to storing maps with enum
|
||||||
|
keys as objects
|
||||||
|
|
||||||
|
## Deprecated functions
|
||||||
|
|
||||||
|
- [**JSON_DELETE_DEPRECATED_FUNCTIONS**](json_delete_deprecated_functions.md) - opt in to deleting the deprecated
|
||||||
|
functions ahead of their removal in version 4.0.0
|
||||||
|
|
||||||
## Comparison behavior
|
## Comparison behavior
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
# JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_DELETE_DEPRECATED_FUNCTIONS /* value */
|
||||||
|
```
|
||||||
|
|
||||||
|
When defined to `1`, all [deprecated functions](../../community/roadmap.md#removal-of-deprecated-functions) of the
|
||||||
|
library are declared as deleted (`= delete`) instead of only being marked as deprecated. Code that still calls one of
|
||||||
|
them no longer compiles. This way, you can find all calls that need to be replaced before version 4.0.0 removes these
|
||||||
|
functions; the [migration guide](../../integration/migration_guide.md#replace-deprecated-functions) describes how.
|
||||||
|
|
||||||
|
A deleted function, unlike a removed one, still takes part in overload resolution. A call that would select it
|
||||||
|
therefore fails to compile instead of silently selecting another overload. This matters for the deprecated
|
||||||
|
`from_*(ptr, len)` overloads of [`from_cbor`](../basic_json/from_cbor.md), [`from_msgpack`](../basic_json/from_msgpack.md),
|
||||||
|
[`from_ubjson`](../basic_json/from_ubjson.md), [`from_bjdata`](../basic_json/from_bjdata.md),
|
||||||
|
[`from_bon8`](../basic_json/from_bon8.md), and [`from_bson`](../basic_json/from_bson.md): without them, a call like
|
||||||
|
`from_cbor(ptr, len)` would compile, read `ptr` as a NUL-terminated string, and convert `len` to the `strict` parameter.
|
||||||
|
|
||||||
|
The macro does not affect the deprecated legacy comparison of discarded values, which is controlled by
|
||||||
|
[`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](json_use_legacy_discarded_value_comparison.md).
|
||||||
|
|
||||||
|
## Default definition
|
||||||
|
|
||||||
|
The default value is `0` (disabled, the deprecated functions can still be called, and the compiler warns about it).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_DELETE_DEPRECATED_FUNCTIONS 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
!!! info "CMake option"
|
||||||
|
|
||||||
|
The macro can also be set with the CMake option
|
||||||
|
[`JSON_DeleteDeprecatedFunctions`](../../integration/cmake.md#json_deletedeprecatedfunctions) (`OFF` by default).
|
||||||
|
|
||||||
|
!!! warning "Opt-in only"
|
||||||
|
|
||||||
|
This macro must be defined **before** including `<nlohmann/json.hpp>`. Defining it after the include has no
|
||||||
|
effect. Define it for the whole project to avoid different declarations of the same class in different
|
||||||
|
translation units.
|
||||||
|
|
||||||
|
!!! note "ABI compatibility"
|
||||||
|
|
||||||
|
The macro only turns calls that compile into calls that do not; it does not change the layout or the behavior of
|
||||||
|
any type. Its value is therefore not encoded in the [namespace](../../features/namespace.md).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example "Example: default behavior (macro not defined)"
|
||||||
|
|
||||||
|
Without the macro, the deprecated overload is called, and the compiler warns about it:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};
|
||||||
|
auto j = json::from_cbor(v.data(), v.size());
|
||||||
|
// warning: 'from_cbor' is deprecated: Since 3.8.0; use from_cbor(ptr, ptr + len)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
??? example "Example: deleted deprecated functions (macro defined to 1)"
|
||||||
|
|
||||||
|
With the macro, the call does not compile:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_DELETE_DEPRECATED_FUNCTIONS 1
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};
|
||||||
|
auto j = json::from_cbor(v.data(), v.size());
|
||||||
|
// error: call to deleted function 'from_cbor'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Roadmap: removal of deprecated functions](../../community/roadmap.md#removal-of-deprecated-functions) - the
|
||||||
|
deprecated functions and the version they were deprecated in
|
||||||
|
- [Migration guide: replace deprecated functions](../../integration/migration_guide.md#replace-deprecated-functions) -
|
||||||
|
how to replace each deprecated function
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
|
- Planned to be removed in version 4.0.0, which removes the deprecated functions. The deprecated `from_*(ptr, len)`
|
||||||
|
overloads stay deleted in version 4.0.0.
|
||||||
@@ -112,3 +112,4 @@ The default value is `0` (disabled — existing behavior is preserved).
|
|||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
- Added in version 3.13.0.
|
||||||
|
- Planned to become the default (with the macro removed) in version 4.0.0.
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ By default, implicit conversions are enabled.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: implicit conversion"
|
??? example "Example: implicit and explicit conversions"
|
||||||
|
|
||||||
This is an example for an implicit conversion:
|
This is an example for an implicit conversion:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
# JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS /* value */
|
||||||
|
```
|
||||||
|
|
||||||
|
When defined to `1`, maps whose keys are enums (such as `std::map<E, T>` or `std::unordered_map<E, T>`) are stored as
|
||||||
|
JSON objects, using the enum's own conversion for the keys. By default, they are stored as arrays of `[key, value]`
|
||||||
|
pairs.
|
||||||
|
|
||||||
|
## Default definition
|
||||||
|
|
||||||
|
The default value is `0` (disabled — existing behavior is preserved).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
!!! note "Background"
|
||||||
|
|
||||||
|
JSON object keys are strings, so a map is only stored as an object if its keys can be converted to a string type.
|
||||||
|
Enums are not, even if [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) maps them to strings, so a
|
||||||
|
map with enum keys becomes an array of `[key, value]` pairs:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[["stopped", "aa"], ["completed", "bb"]]
|
||||||
|
```
|
||||||
|
|
||||||
|
With this macro, the same map becomes an object
|
||||||
|
(see [#4378](https://github.com/nlohmann/json/issues/4378)):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"completed": "bb", "stopped": "aa"}
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! note "Maps with non-unique keys"
|
||||||
|
|
||||||
|
Maps that allow duplicate keys, such as `std::multimap<E, T>` or `std::unordered_multimap<E, T>`, are not affected
|
||||||
|
by the macro and are still stored as arrays of `[key, value]` pairs, as an object cannot hold duplicate keys.
|
||||||
|
|
||||||
|
!!! note "Reading"
|
||||||
|
|
||||||
|
Reading is not affected by the macro: a map with enum keys can always be read from both an array of pairs and an
|
||||||
|
object. For the latter, each key is converted to the enum with its `from_json` function, e.g., the one defined by
|
||||||
|
[`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md). Data written without the macro can therefore
|
||||||
|
still be read after enabling it.
|
||||||
|
|
||||||
|
!!! warning "Keys must serialize to distinct strings"
|
||||||
|
|
||||||
|
Each key is converted with the enum's `to_json` function. If a key is not converted to a string (for instance, an
|
||||||
|
enum without [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md), which is stored as an integer, or an
|
||||||
|
enumerator mapped to `nullptr`), [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) is thrown.
|
||||||
|
If two keys are converted to the same string (for instance, because
|
||||||
|
[`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) maps an unlisted enumerator to the first entry),
|
||||||
|
[`type_error.318`](../../home/exceptions.md#jsonexceptiontype_error318) is thrown. In both cases, the target value
|
||||||
|
is not changed.
|
||||||
|
|
||||||
|
!!! warning "Opt-in only"
|
||||||
|
|
||||||
|
This macro must be defined **before** including `<nlohmann/json.hpp>`. Defining it after the include has no effect.
|
||||||
|
|
||||||
|
!!! note "ABI compatibility"
|
||||||
|
|
||||||
|
The value of this macro is encoded in the [namespace](../../features/namespace.md) (tag `_ekmo`), 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.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example "Example: default behavior (macro not defined)"
|
||||||
|
|
||||||
|
Without the macro, a map with enum keys is stored as an array of pairs:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <map>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
enum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {
|
||||||
|
{TS_STOPPED, "stopped"},
|
||||||
|
{TS_RUNNING, "running"},
|
||||||
|
{TS_COMPLETED, "completed"},
|
||||||
|
})
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::map<TaskState, std::string> m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
||||||
|
|
||||||
|
json j = m;
|
||||||
|
// j is [["stopped","aa"],["completed","bb"]]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
??? example "Example: objects for enum-keyed maps (macro defined to 1)"
|
||||||
|
|
||||||
|
With the macro, the same map is stored as an object:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 1
|
||||||
|
#include <map>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
enum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };
|
||||||
|
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {
|
||||||
|
{TS_STOPPED, "stopped"},
|
||||||
|
{TS_RUNNING, "running"},
|
||||||
|
{TS_COMPLETED, "completed"},
|
||||||
|
})
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::map<TaskState, std::string> m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
||||||
|
|
||||||
|
json j = m;
|
||||||
|
// j is {"completed":"bb","stopped":"aa"}
|
||||||
|
|
||||||
|
auto m2 = j.get<std::map<TaskState, std::string>>();
|
||||||
|
// m2 == m
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Specializing enum conversion](../../features/enum_conversion.md)
|
||||||
|
- [**NLOHMANN_JSON_SERIALIZE_ENUM**](nlohmann_json_serialize_enum.md) - serialize/deserialize an enum
|
||||||
|
- [**NLOHMANN_JSON_SERIALIZE_ENUM_STRICT**](nlohmann_json_serialize_enum_strict.md) - serialize/deserialize an enum with
|
||||||
|
exceptions
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -41,6 +41,9 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
conversion. Select this default pair carefully. See example 1 below.
|
conversion. Select this default pair carefully. See example 1 below.
|
||||||
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
||||||
list will be returned when converting to or from JSON. See example 2 below.
|
list will be returned when converting to or from JSON. See example 2 below.
|
||||||
|
- Maps with enum keys (e.g., `std::map<ENUM_TYPE, T>`) are stored as arrays of `[key, value]` pairs by default.
|
||||||
|
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.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -80,6 +83,7 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
- [Specializing enum conversion](../../features/enum_conversion.md)
|
- [Specializing enum conversion](../../features/enum_conversion.md)
|
||||||
- [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](./nlohmann_json_serialize_enum_strict.md)
|
- [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](./nlohmann_json_serialize_enum_strict.md)
|
||||||
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
||||||
|
- [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md)
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
`"enum value out of range for <type>"`.
|
`"enum value out of range for <type>"`.
|
||||||
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
||||||
list will be returned when converting to or from JSON. See example 2 below.
|
list will be returned when converting to or from JSON. See example 2 below.
|
||||||
|
- Maps with enum keys (e.g., `std::map<ENUM_TYPE, T>`) are stored as arrays of `[key, value]` pairs by default.
|
||||||
|
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.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -99,6 +102,7 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
- [Specializing enum conversion](../../features/enum_conversion.md)
|
- [Specializing enum conversion](../../features/enum_conversion.md)
|
||||||
- [`NLOHMANN_JSON_SERIALIZE_ENUM`](./nlohmann_json_serialize_enum.md)
|
- [`NLOHMANN_JSON_SERIALIZE_ENUM`](./nlohmann_json_serialize_enum.md)
|
||||||
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
|
||||||
|
- [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md)
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ The following macros guard changes that are planned to become the default in ver
|
|||||||
| [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) | `0` | `1`: reading from a stream does not consume the character after a number | – | 3.13.0 |
|
| [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) | `0` | `1`: reading from a stream does not consume the character after a number | – | 3.13.0 |
|
||||||
| [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) | `0` | `1`: a NUL byte in the input is a parse error instead of the end of input | [`JSON_StrictNulHandling`](../integration/cmake.md#json_strictnulhandling) | 3.13.0 |
|
| [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) | `0` | `1`: a NUL byte in the input is a parse error instead of the end of input | [`JSON_StrictNulHandling`](../integration/cmake.md#json_strictnulhandling) | 3.13.0 |
|
||||||
| [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) | `0` | `1`: `to_cbor`, `to_ubjson`, `to_bjdata`, and `to_bson` throw for strings that are not valid UTF-8 by default | [`JSON_StrictBinaryUTF8`](../integration/cmake.md#json_strictbinaryutf8) | 3.13.0 |
|
| [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) | `0` | `1`: `to_cbor`, `to_ubjson`, `to_bjdata`, and `to_bson` throw for strings that are not valid UTF-8 by default | [`JSON_StrictBinaryUTF8`](../integration/cmake.md#json_strictbinaryutf8) | 3.13.0 |
|
||||||
|
| [`JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md) | `0` | `1`: a `basic_json` value can no longer be created from a one-element tuple of a reference to it, such as `std::forward_as_tuple(j)`| [`JSON_DisableTupleReferenceConversion`](../integration/cmake.md#json_disabletuplereferenceconversion) | 3.13.0 |
|
||||||
|
| [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) | `0` | removed: the deprecated functions are removed (see below); the `from_*(ptr, len)` overloads stay deleted | [`JSON_DeleteDeprecatedFunctions`](../integration/cmake.md#json_deletedeprecatedfunctions) | 3.13.0 |
|
||||||
|
|
||||||
For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:
|
For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:
|
||||||
|
|
||||||
@@ -75,6 +77,8 @@ For example, the following makes a 3.x release behave like version 4.0 with resp
|
|||||||
#define JSON_PRECISE_STREAM_POSITION 1
|
#define JSON_PRECISE_STREAM_POSITION 1
|
||||||
#define JSON_STRICT_NUL_HANDLING 1
|
#define JSON_STRICT_NUL_HANDLING 1
|
||||||
#define JSON_STRICT_BINARY_UTF8 1
|
#define JSON_STRICT_BINARY_UTF8 1
|
||||||
|
#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 1
|
||||||
|
#define JSON_DELETE_DEPRECATED_FUNCTIONS 1
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -84,8 +88,13 @@ way to achieve this.
|
|||||||
### Removal of deprecated functions
|
### Removal of deprecated functions
|
||||||
|
|
||||||
Version 4.0 will remove all deprecated functions. Compiling with deprecation warnings enabled shows which of them your
|
Version 4.0 will remove all deprecated functions. Compiling with deprecation warnings enabled shows which of them your
|
||||||
code still uses. The [migration guide](../integration/migration_guide.md#replace-deprecated-functions) shows how to
|
code still uses. Defining [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) to
|
||||||
replace each of them.
|
`1` turns these warnings into errors, as the deprecated functions are then deleted. The
|
||||||
|
[migration guide](../integration/migration_guide.md#replace-deprecated-functions) shows how to replace each of them.
|
||||||
|
|
||||||
|
The `from_*` overloads taking a pointer and a length are not removed in version 4.0, but stay deleted. Without them, a
|
||||||
|
call like `from_cbor(ptr, len)` would still compile: it would read `ptr` as a NUL-terminated string and convert `len`
|
||||||
|
to the `strict` parameter.
|
||||||
|
|
||||||
| Deprecated | Since | Migration |
|
| Deprecated | Since | Migration |
|
||||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
||||||
@@ -97,6 +106,7 @@ replace each of them.
|
|||||||
| [`json_pointer::operator string_t`](../api/json_pointer/operator_string_t.md) | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
| [`json_pointer::operator string_t`](../api/json_pointer/operator_string_t.md) | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
||||||
| [`json_pointer`](../api/json_pointer/index.md) with a `basic_json` type as template argument, and the overloads of `value`, `contains`, `operator[]`, and `at` accepting such a pointer | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
| [`json_pointer`](../api/json_pointer/index.md) with a `basic_json` type as template argument, and the overloads of `value`, `contains`, `operator[]`, and `at` accepting such a pointer | 3.11.0 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
||||||
| Comparing a [`json_pointer`](../api/json_pointer/index.md) with a string via [`operator==`](../api/json_pointer/operator_eq.md) or [`operator!=`](../api/json_pointer/operator_ne.md) | 3.11.2 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
| Comparing a [`json_pointer`](../api/json_pointer/index.md) with a string via [`operator==`](../api/json_pointer/operator_eq.md) or [`operator!=`](../api/json_pointer/operator_ne.md) | 3.11.2 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
||||||
|
| [`from_bjdata`](../api/basic_json/from_bjdata.md) and [`from_bon8`](../api/basic_json/from_bon8.md) with `(ptr, len)` | 3.13.0 | [Parsing](../integration/migration_guide.md#parsing) |
|
||||||
|
|
||||||
The deprecated legacy comparison of discarded values is controlled by a macro and therefore listed in the table above.
|
The deprecated legacy comparison of discarded values is controlled by a macro and therefore listed in the table above.
|
||||||
|
|
||||||
|
|||||||
@@ -168,9 +168,9 @@ The library maps CBOR types to JSON value types as follows:
|
|||||||
!!! warning "Negative integer overflow"
|
!!! warning "Negative integer overflow"
|
||||||
|
|
||||||
CBOR negative integers (major type 1) are decoded as `-1 - n`. If the encoded magnitude `n` is too large for the
|
CBOR negative integers (major type 1) are decoded as `-1 - n`. If the encoded magnitude `n` is too large for the
|
||||||
result to fit into `number_integer_t` (`std::int64_t` by default), parsing fails with a
|
result to fit into `number_integer_t` (`std::int64_t` by default), the result is stored as `number_float_t`, like
|
||||||
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) exception rather than overflowing
|
a too small integer in JSON text. For example, `-18446744073709551616` (`0x3B` followed by eight `0xFF` bytes) is
|
||||||
silently.
|
stored as `-1.8446744073709552e+19`.
|
||||||
|
|
||||||
!!! warning "Object keys"
|
!!! warning "Object keys"
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,23 @@ assert(jPi.get<TaskState>() == TS_INVALID );
|
|||||||
--8<-- "examples/nlohmann_json_serialize_enum.output"
|
--8<-- "examples/nlohmann_json_serialize_enum.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Maps with enum keys
|
||||||
|
|
||||||
|
By default, maps with enum keys, such as `std::map<TaskState, std::string>`, are stored as arrays of `[key, value]`
|
||||||
|
pairs, because JSON object keys must be strings. Define
|
||||||
|
[`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md) before including the
|
||||||
|
library to store them as objects, with the keys converted by the enum's `to_json()` function:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::map<TaskState, std::string> m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
||||||
|
|
||||||
|
json j = m;
|
||||||
|
// default: [["stopped","aa"],["completed","bb"]]
|
||||||
|
// with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS: {"completed":"bb","stopped":"aa"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Either form can be read back, with or without the macro.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
Just as in [Arbitrary Type Conversions](arbitrary_types.md) above,
|
Just as in [Arbitrary Type Conversions](arbitrary_types.md) above,
|
||||||
|
|||||||
@@ -23,6 +23,17 @@ This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/
|
|||||||
|
|
||||||
See [full documentation of `JSON_CATCH_USER(exception)`](../api/macros/json_throw_user.md).
|
See [full documentation of `JSON_CATCH_USER(exception)`](../api/macros/json_throw_user.md).
|
||||||
|
|
||||||
|
## `JSON_DELETE_DEPRECATED_FUNCTIONS`
|
||||||
|
|
||||||
|
When defined to `1`, all deprecated functions are declared as deleted instead of only being marked as deprecated, so
|
||||||
|
code that still calls them no longer compiles. This way, you can find all calls that need to be replaced before version
|
||||||
|
4.0.0 removes these functions.
|
||||||
|
|
||||||
|
The macro can also be set with the CMake option
|
||||||
|
[`JSON_DeleteDeprecatedFunctions`](../integration/cmake.md#json_deletedeprecatedfunctions) (`OFF` by default).
|
||||||
|
|
||||||
|
See [full documentation of `JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md).
|
||||||
|
|
||||||
## `JSON_DIAGNOSTICS`
|
## `JSON_DIAGNOSTICS`
|
||||||
|
|
||||||
This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable
|
This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable
|
||||||
@@ -86,7 +97,8 @@ See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json
|
|||||||
## `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`
|
## `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`
|
||||||
|
|
||||||
When defined to `1`, a JSON value can no longer be created from a one-element `std::tuple` holding a reference to a JSON
|
When defined to `1`, a JSON value can no longer be created from a one-element `std::tuple` holding a reference to a JSON
|
||||||
value, such as the result of `std::forward_as_tuple(j)`. This lets `std::tuple` convert such tuples element-wise.
|
value, such as the result of `std::forward_as_tuple(j)`. This lets `std::tuple` convert such tuples element-wise. This
|
||||||
|
is planned to become the default in version 4.0.0.
|
||||||
|
|
||||||
See [full documentation of `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md).
|
See [full documentation of `JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md).
|
||||||
|
|
||||||
@@ -198,6 +210,13 @@ default.
|
|||||||
|
|
||||||
See [full documentation of `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md).
|
See [full documentation of `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md).
|
||||||
|
|
||||||
|
## `JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`
|
||||||
|
|
||||||
|
When defined to `1`, maps with enum keys (e.g., `std::map<E, T>`) are stored as objects, using the enum's conversion for
|
||||||
|
the keys, instead of arrays of `[key, value]` pairs. It is switched off (`0`) by default.
|
||||||
|
|
||||||
|
See [full documentation of `JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md).
|
||||||
|
|
||||||
## `JSON_USE_SIMDUTF`
|
## `JSON_USE_SIMDUTF`
|
||||||
|
|
||||||
When defined, UTF-8 validation of JSON strings read from contiguous byte input is delegated to the
|
When defined, UTF-8 validation of JSON strings read from contiguous byte input is delegated to the
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ The complete default namespace name is derived as follows:
|
|||||||
- [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) defined non-zero appends `_psp`.
|
- [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) defined non-zero appends `_psp`.
|
||||||
- [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) defined non-zero appends `_snul`.
|
- [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) defined non-zero appends `_snul`.
|
||||||
- [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) defined non-zero appends `_sbu8`.
|
- [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) defined non-zero appends `_sbu8`.
|
||||||
|
- [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md) defined non-zero
|
||||||
|
appends `_ekmo`.
|
||||||
- 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.
|
||||||
|
|||||||
@@ -331,9 +331,6 @@ An unexpected byte was read in a [binary format](../features/binary_formats/inde
|
|||||||
[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1
|
[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: negative integer overflow
|
|
||||||
```
|
|
||||||
```
|
|
||||||
[json.exception.parse_error.112] parse error at byte 5: syntax error while parsing BSON document: document size 6 does not match the number of bytes read (5)
|
[json.exception.parse_error.112] parse error at byte 5: syntax error while parsing BSON document: document size 6 does not match the number of bytes read (5)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -599,6 +596,9 @@ During implicit or explicit value conversion, the JSON type must be compatible w
|
|||||||
[json.exception.type_error.302] type must be string, but is object
|
[json.exception.type_error.302] type must be string, but is object
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This exception is also thrown with [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md)
|
||||||
|
if a key of a map with enum keys is not converted to a string, for instance, because the enum is stored as an integer.
|
||||||
|
|
||||||
### json.exception.type_error.303
|
### json.exception.type_error.303
|
||||||
|
|
||||||
To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`.
|
To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`.
|
||||||
@@ -791,6 +791,19 @@ The dynamic type of the object cannot be represented in the requested serializat
|
|||||||
|
|
||||||
Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {"value": true}`
|
Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {"value": true}`
|
||||||
|
|
||||||
|
### json.exception.type_error.318
|
||||||
|
|
||||||
|
With [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md), a map with enum
|
||||||
|
keys is stored as an object. This exception is thrown if two of its keys are converted to the same string, so one of the
|
||||||
|
entries would be lost. This happens, for instance, if [`NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md)
|
||||||
|
does not list an enumerator and it is therefore converted like the first listed one.
|
||||||
|
|
||||||
|
!!! failure "Example message"
|
||||||
|
|
||||||
|
```
|
||||||
|
[json.exception.type_error.318] duplicate object key 'red'
|
||||||
|
```
|
||||||
|
|
||||||
## Out of range
|
## Out of range
|
||||||
|
|
||||||
This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys.
|
This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys.
|
||||||
@@ -863,13 +876,18 @@ The JSON Patch operations 'remove' and 'add' cannot be applied to the root eleme
|
|||||||
|
|
||||||
### json.exception.out_of_range.406
|
### json.exception.out_of_range.406
|
||||||
|
|
||||||
A parsed number could not be stored as without changing it to NaN or INF.
|
A parsed number could not be stored without changing it to NaN or INF. For the binary formats, this happens when a
|
||||||
|
finite floating-point number does not fit into [`number_float_t`](../api/basic_json/number_float_t.md), for example a
|
||||||
|
double-precision number when `number_float_t` is `#!cpp float`.
|
||||||
|
|
||||||
!!! failure "Example message"
|
!!! failure "Example messages"
|
||||||
|
|
||||||
```
|
```
|
||||||
number overflow parsing '10E1000'
|
number overflow parsing '10E1000'
|
||||||
```
|
```
|
||||||
|
```
|
||||||
|
[json.exception.out_of_range.406] syntax error while parsing CBOR value: number overflow
|
||||||
|
```
|
||||||
|
|
||||||
### json.exception.out_of_range.407
|
### json.exception.out_of_range.407
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,12 @@ Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/
|
|||||||
|
|
||||||
Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default.
|
Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default.
|
||||||
|
|
||||||
|
### `JSON_DeleteDeprecatedFunctions`
|
||||||
|
|
||||||
|
Delete the deprecated functions instead of only deprecating them by defining the macro
|
||||||
|
[`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md). This option is `OFF` by
|
||||||
|
default.
|
||||||
|
|
||||||
### `JSON_Diagnostics`
|
### `JSON_Diagnostics`
|
||||||
|
|
||||||
Enable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This option is `OFF` by default.
|
Enable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This option is `OFF` by default.
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ deprecations are annotated with
|
|||||||
[`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which
|
[`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which
|
||||||
function to use instead.
|
function to use instead.
|
||||||
|
|
||||||
|
!!! tip "Find all calls of deprecated functions"
|
||||||
|
|
||||||
|
Define [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) to `1` (or set the
|
||||||
|
CMake option [`JSON_DeleteDeprecatedFunctions`](cmake.md#json_deletedeprecatedfunctions)) to delete all deprecated
|
||||||
|
functions. Every remaining call then fails to compile, even if deprecation warnings are disabled, so your code is
|
||||||
|
ready for version 4.0.0 once it compiles with the macro.
|
||||||
|
|
||||||
### Parsing
|
### Parsing
|
||||||
|
|
||||||
- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use
|
- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use
|
||||||
@@ -41,8 +48,10 @@ function to use instead.
|
|||||||
[`from_ubjson`](../api/basic_json/from_ubjson.md), and [`from_bson`](../api/basic_json/from_bson.md)) via initializer
|
[`from_ubjson`](../api/basic_json/from_ubjson.md), and [`from_bson`](../api/basic_json/from_bson.md)) via initializer
|
||||||
lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of
|
lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of
|
||||||
`from_cbor({ptr, len})`. Likewise, passing a pointer and a length as two separate arguments to `from_cbor`,
|
`from_cbor({ptr, len})`. Likewise, passing a pointer and a length as two separate arguments to `from_cbor`,
|
||||||
`from_msgpack`, `from_ubjson`, and `from_bson` is deprecated since 3.8.0; call `from_cbor(ptr, ptr+len)` instead of
|
`from_msgpack`, `from_ubjson`, and `from_bson` is deprecated since 3.8.0, and to
|
||||||
`from_cbor(ptr, len)`.
|
[`from_bjdata`](../api/basic_json/from_bjdata.md) and [`from_bon8`](../api/basic_json/from_bon8.md) since 3.13.0; call
|
||||||
|
`from_cbor(ptr, ptr+len)` instead of `from_cbor(ptr, len)`. These overloads will not be removed in version 4.0.0, but
|
||||||
|
deleted, so a call like `from_cbor(ptr, len)` cannot compile and convert `len` to the `strict` parameter.
|
||||||
|
|
||||||
=== "Deprecated"
|
=== "Deprecated"
|
||||||
|
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ nav:
|
|||||||
- 'JSON_BRACE_INIT_COPY_SEMANTICS': api/macros/json_brace_init_copy_semantics.md
|
- 'JSON_BRACE_INIT_COPY_SEMANTICS': api/macros/json_brace_init_copy_semantics.md
|
||||||
- 'JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER': api/macros/json_throw_user.md
|
- 'JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER': api/macros/json_throw_user.md
|
||||||
- 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md
|
- 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md
|
||||||
|
- 'JSON_DELETE_DEPRECATED_FUNCTIONS': api/macros/json_delete_deprecated_functions.md
|
||||||
- 'JSON_DIAGNOSTIC_POSITIONS': api/macros/json_diagnostic_positions.md
|
- 'JSON_DIAGNOSTIC_POSITIONS': api/macros/json_diagnostic_positions.md
|
||||||
- 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md
|
- 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md
|
||||||
- 'JSON_DISABLE_TUPLE_REFERENCE_CONVERSION': api/macros/json_disable_tuple_reference_conversion.md
|
- 'JSON_DISABLE_TUPLE_REFERENCE_CONVERSION': api/macros/json_disable_tuple_reference_conversion.md
|
||||||
@@ -313,6 +314,7 @@ nav:
|
|||||||
- 'JSON_USE_GLOBAL_UDLS': api/macros/json_use_global_udls.md
|
- 'JSON_USE_GLOBAL_UDLS': api/macros/json_use_global_udls.md
|
||||||
- 'JSON_USE_IMPLICIT_CONVERSIONS': api/macros/json_use_implicit_conversions.md
|
- 'JSON_USE_IMPLICIT_CONVERSIONS': api/macros/json_use_implicit_conversions.md
|
||||||
- '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_SIMDUTF': api/macros/json_use_simdutf.md
|
- 'JSON_USE_SIMDUTF': api/macros/json_use_simdutf.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
|
||||||
|
|||||||
@@ -50,6 +50,10 @@
|
|||||||
#define JSON_STRICT_BINARY_UTF8 0
|
#define JSON_STRICT_BINARY_UTF8 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
||||||
#else
|
#else
|
||||||
@@ -92,14 +96,20 @@
|
|||||||
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8
|
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS _ekmo
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#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) json_abi ## a ## b ## c ## d ## e ## f ## g
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h) json_abi ## a ## b ## c ## d ## e ## f ## g ## h
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h) \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g)
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h)
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
||||||
@@ -109,7 +119,8 @@
|
|||||||
NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS, \
|
NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS, \
|
||||||
NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION, \
|
NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION, \
|
||||||
NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING, \
|
NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING, \
|
||||||
NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8)
|
NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8, \
|
||||||
|
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS)
|
||||||
|
|
||||||
// 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) \
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ inline void from_json(const BasicJsonType& j, EnumType& e)
|
|||||||
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
||||||
value_type val;
|
value_type val;
|
||||||
get_arithmetic_value(j, val);
|
get_arithmetic_value(j, val);
|
||||||
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
e = static_cast<EnumType>(bool_aware_static_cast<underlying_type>(val));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
@@ -530,11 +530,40 @@ void from_json_pair_array_to_map(const BasicJsonType& j, MapType& m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read a map with enum keys from an object, using the enum's own from_json for
|
||||||
|
// the keys (e.g., from NLOHMANN_JSON_SERIALIZE_ENUM); this is the form written
|
||||||
|
// with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
template<typename BasicJsonType, typename Map>
|
||||||
|
inline bool from_json_enum_keyed_object(const BasicJsonType& j, Map& m, std::true_type /*key is enum*/)
|
||||||
|
{
|
||||||
|
if (!j.is_object())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m.clear();
|
||||||
|
for (const auto& p : *j.template get_ptr<const typename BasicJsonType::object_t*>())
|
||||||
|
{
|
||||||
|
m.emplace(BasicJsonType(p.first).template get<typename Map::key_type>(), p.second.template get<typename Map::mapped_type>());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename Map>
|
||||||
|
inline bool from_json_enum_keyed_object(const BasicJsonType& /*j*/, Map& /*m*/, std::false_type /*key is enum*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
||||||
typename = enable_if_t < !std::is_constructible <
|
typename = enable_if_t < !std::is_constructible <
|
||||||
typename BasicJsonType::string_t, Key >::value >>
|
typename BasicJsonType::string_t, Key >::value >>
|
||||||
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
||||||
{
|
{
|
||||||
|
// NOLINTNEXTLINE(modernize-type-traits) we use C++11
|
||||||
|
if (from_json_enum_keyed_object(j, m, std::is_enum<Key> {}))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
from_json_pair_array_to_map(j, m);
|
from_json_pair_array_to_map(j, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,6 +572,11 @@ template < typename BasicJsonType, typename Key, typename Value, typename Hash,
|
|||||||
typename BasicJsonType::string_t, Key >::value >>
|
typename BasicJsonType::string_t, Key >::value >>
|
||||||
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
||||||
{
|
{
|
||||||
|
// NOLINTNEXTLINE(modernize-type-traits) we use C++11
|
||||||
|
if (from_json_enum_keyed_object(j, m, std::is_enum<Key> {}))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
from_json_pair_array_to_map(j, m);
|
from_json_pair_array_to_map(j, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <valarray> // valarray
|
#include <valarray> // valarray
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
|
#include <nlohmann/detail/exceptions.hpp>
|
||||||
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
|
||||||
#include <nlohmann/detail/meta/cpp_future.hpp>
|
#include <nlohmann/detail/meta/cpp_future.hpp>
|
||||||
#include <nlohmann/detail/meta/std_fs.hpp>
|
#include <nlohmann/detail/meta/std_fs.hpp>
|
||||||
@@ -364,7 +365,7 @@ inline void to_json(BasicJsonType& j, EnumType e) noexcept
|
|||||||
{
|
{
|
||||||
using underlying_type = typename std::underlying_type<EnumType>::type;
|
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||||
static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
|
static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
|
||||||
external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
|
external_constructor<integral_value_t>::construct(j, bool_aware_static_cast<underlying_type>(e));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
@@ -384,6 +385,9 @@ template < typename BasicJsonType, typename CompatibleArrayType,
|
|||||||
!is_basic_json<CompatibleArrayType>::value
|
!is_basic_json<CompatibleArrayType>::value
|
||||||
#if JSON_HAS_RANGE_VIEW_CONVERSION
|
#if JSON_HAS_RANGE_VIEW_CONVERSION
|
||||||
&& !is_compatible_range_view<CompatibleArrayType>::value
|
&& !is_compatible_range_view<CompatibleArrayType>::value
|
||||||
|
#endif
|
||||||
|
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
&& !is_enum_keyed_map<CompatibleArrayType>::value
|
||||||
#endif
|
#endif
|
||||||
,
|
,
|
||||||
int > = 0 >
|
int > = 0 >
|
||||||
@@ -438,6 +442,33 @@ inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
|
|||||||
external_constructor<value_t::object>::construct(j, obj);
|
external_constructor<value_t::object>::construct(j, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
// store a map with enum keys as an object, using the enum's own to_json for the
|
||||||
|
// keys (e.g., from NLOHMANN_JSON_SERIALIZE_ENUM); without the macro, such maps
|
||||||
|
// are stored as arrays of [key, value] pairs
|
||||||
|
template < typename BasicJsonType, typename EnumKeyedMap,
|
||||||
|
enable_if_t < is_enum_keyed_map<EnumKeyedMap>::value&& !is_basic_json<EnumKeyedMap>::value, int > = 0 >
|
||||||
|
inline void to_json(BasicJsonType& j, const EnumKeyedMap& map)
|
||||||
|
{
|
||||||
|
typename BasicJsonType::object_t obj;
|
||||||
|
for (const auto& p : map)
|
||||||
|
{
|
||||||
|
BasicJsonType key = p.first;
|
||||||
|
if (JSON_HEDLEY_UNLIKELY(!key.is_string()))
|
||||||
|
{
|
||||||
|
JSON_THROW(type_error::create(302, concat("type must be string, but is ", key.type_name()), &key));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& key_string = *key.template get_ptr<typename BasicJsonType::string_t*>();
|
||||||
|
if (JSON_HEDLEY_UNLIKELY(!obj.emplace(key_string, BasicJsonType(p.second)).second))
|
||||||
|
{
|
||||||
|
JSON_THROW(type_error::create(318, concat("duplicate object key '", key_string, "'"), &key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
external_constructor<value_t::object>::construct(j, std::move(obj));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -81,9 +81,13 @@ class json_pointer
|
|||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_string_t/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_string_t/
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string())
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string())
|
||||||
operator string_t() const
|
operator string_t() const
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return to_string();
|
return to_string();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef JSON_NO_IO
|
#ifndef JSON_NO_IO
|
||||||
/// @brief write string representation of the JSON pointer to stream
|
/// @brief write string representation of the JSON pointer to stream
|
||||||
@@ -1022,9 +1026,13 @@ class json_pointer
|
|||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
|
||||||
bool operator==(const string_t& rhs) const
|
bool operator==(const string_t& rhs) const
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return *this == json_pointer(rhs);
|
return *this == json_pointer(rhs);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief 3-way compares two JSON pointers
|
/// @brief 3-way compares two JSON pointers
|
||||||
template<typename RefStringTypeRhs>
|
template<typename RefStringTypeRhs>
|
||||||
@@ -1102,18 +1110,26 @@ template<typename RefStringTypeLhs,
|
|||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
||||||
inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
|
||||||
const StringType& rhs)
|
const StringType& rhs)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return lhs == json_pointer<RefStringTypeLhs>(rhs);
|
return lhs == json_pointer<RefStringTypeLhs>(rhs);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename RefStringTypeRhs,
|
template<typename RefStringTypeRhs,
|
||||||
typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer))
|
||||||
inline bool operator==(const StringType& lhs,
|
inline bool operator==(const StringType& lhs,
|
||||||
const json_pointer<RefStringTypeRhs>& rhs)
|
const json_pointer<RefStringTypeRhs>& rhs)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return json_pointer<RefStringTypeRhs>(lhs) == rhs;
|
return json_pointer<RefStringTypeRhs>(lhs) == rhs;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
||||||
@@ -1127,18 +1143,26 @@ template<typename RefStringTypeLhs,
|
|||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
||||||
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
|
||||||
const StringType& rhs)
|
const StringType& rhs)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename RefStringTypeRhs,
|
template<typename RefStringTypeRhs,
|
||||||
typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer))
|
||||||
inline bool operator!=(const StringType& lhs,
|
inline bool operator!=(const StringType& lhs,
|
||||||
const json_pointer<RefStringTypeRhs>& rhs)
|
const json_pointer<RefStringTypeRhs>& rhs)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
template<typename RefStringTypeLhs, typename RefStringTypeRhs>
|
||||||
inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
|
inline bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
|
||||||
|
|||||||
@@ -888,6 +888,10 @@
|
|||||||
#define JSON_DISABLE_ENUM_SERIALIZATION 0
|
#define JSON_DISABLE_ENUM_SERIALIZATION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
#define JSON_DELETE_DEPRECATED_FUNCTIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef JSON_DISABLE_TUPLE_REFERENCE_CONVERSION
|
#ifndef JSON_DISABLE_TUPLE_REFERENCE_CONVERSION
|
||||||
#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 0
|
#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -43,6 +43,8 @@
|
|||||||
#undef JSON_PRECISE_STREAM_POSITION
|
#undef JSON_PRECISE_STREAM_POSITION
|
||||||
#undef JSON_STRICT_NUL_HANDLING
|
#undef JSON_STRICT_NUL_HANDLING
|
||||||
#undef JSON_STRICT_BINARY_UTF8
|
#undef JSON_STRICT_BINARY_UTF8
|
||||||
|
#undef JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
#undef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
|
#include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
|
||||||
|
|||||||
@@ -438,6 +438,30 @@ template<typename BasicJsonType, typename CompatibleObjectType>
|
|||||||
struct is_compatible_object_type
|
struct is_compatible_object_type
|
||||||
: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
|
: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using insert_result_t = decltype(std::declval<T&>().insert(std::declval<const value_type_t<T>&>()));
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using insert_result_second_t = decltype(std::declval<T&>().insert(std::declval<const value_type_t<T>&>()).second);
|
||||||
|
|
||||||
|
// a map-like type (std::map, std::unordered_map, ...) whose keys are enums; see
|
||||||
|
// JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct is_enum_keyed_map : std::false_type {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_enum_keyed_map <
|
||||||
|
T, enable_if_t < is_detected<mapped_type_t, T>::value&&
|
||||||
|
is_detected<key_type_t, T>::value >>
|
||||||
|
{
|
||||||
|
// maps with non-unique keys (std::multimap, std::unordered_multimap, ...)
|
||||||
|
// are excluded, because an object cannot hold duplicate keys; they are
|
||||||
|
// detected by insert() returning an iterator instead of a pair<iterator, bool>
|
||||||
|
// NOLINTNEXTLINE(modernize-type-traits) we use C++11
|
||||||
|
static constexpr bool value = std::is_enum<typename T::key_type>::value &&
|
||||||
|
!(is_detected<insert_result_t, T>::value && !is_detected<insert_result_second_t, T>::value);
|
||||||
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleObjectType,
|
template<typename BasicJsonType, typename ConstructibleObjectType,
|
||||||
typename = void>
|
typename = void>
|
||||||
struct is_constructible_object_type_impl : std::false_type {};
|
struct is_constructible_object_type_impl : std::false_type {};
|
||||||
@@ -882,6 +906,21 @@ T conditional_static_cast(U value)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// like conditional_static_cast, but converts to bool by comparing with zero,
|
||||||
|
// because MSVC 2015 warns about any conversion to bool (C4800), even with an
|
||||||
|
// explicit cast; used for enums whose underlying type is bool
|
||||||
|
template < typename T, typename U, enable_if_t < !std::is_same<T, bool>::value, int > = 0 >
|
||||||
|
T bool_aware_static_cast(U value)
|
||||||
|
{
|
||||||
|
return conditional_static_cast<T>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename U, enable_if_t<std::is_same<T, bool>::value, int> = 0>
|
||||||
|
bool bool_aware_static_cast(U value)
|
||||||
|
{
|
||||||
|
return value != U();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
using all_integral = conjunction<std::is_integral<Types>...>;
|
using all_integral = conjunction<std::is_integral<Types>...>;
|
||||||
|
|
||||||
|
|||||||
+147
-14
@@ -3492,9 +3492,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
|
&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||||
ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
|
ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return value(ptr.convert(), default_value);
|
return value(ptr.convert(), default_value);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
|
template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
|
||||||
detail::enable_if_t <
|
detail::enable_if_t <
|
||||||
@@ -3503,9 +3507,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
|
&& !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||||
ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
|
ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return value(ptr.convert(), std::forward<ValueType>(default_value));
|
return value(ptr.convert(), std::forward<ValueType>(default_value));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief access the first element
|
/// @brief access the first element
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/front/
|
/// @sa https://json.nlohmann.me/api/basic_json/front/
|
||||||
@@ -3863,9 +3871,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||||
bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return ptr.contains(this);
|
return ptr.contains(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -3976,9 +3988,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
|
/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
|
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
|
||||||
static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
|
static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return ref.items();
|
return ref.items();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief wrapper to access iterator member functions in range-based for
|
/// @brief wrapper to access iterator member functions in range-based for
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/items/
|
/// @sa https://json.nlohmann.me/api/basic_json/items/
|
||||||
@@ -3987,9 +4003,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
|
/// that is, replace `json::iterator_wrapper(j)` with `j.items()`.
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
|
JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
|
||||||
static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
|
static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return ref.items();
|
return ref.items();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief helper to access iterator member functions in range-based for
|
/// @brief helper to access iterator member functions in range-based for
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/items/
|
/// @sa https://json.nlohmann.me/api/basic_json/items/
|
||||||
@@ -5078,7 +5098,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
requires std::is_scalar_v<ScalarType>
|
requires std::is_scalar_v<ScalarType>
|
||||||
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) <= rhs;
|
return basic_json(lhs) <= rhs;
|
||||||
}
|
}
|
||||||
@@ -5087,7 +5107,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
requires std::is_scalar_v<ScalarType>
|
requires std::is_scalar_v<ScalarType>
|
||||||
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) >= rhs;
|
return basic_json(lhs) >= rhs;
|
||||||
}
|
}
|
||||||
@@ -5108,11 +5128,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The friend comparisons with a scalar name the JSON type via decltype of
|
||||||
|
// their parameter in noexcept, because older MSVC versions do not see the
|
||||||
|
// class scope there: MSVC 2015 and 2017 take basic_json as the template,
|
||||||
|
// and MSVC 2019 16.0 rejects member types and template parameters.
|
||||||
|
|
||||||
/// @brief comparison: equal
|
/// @brief comparison: equal
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs == basic_json(rhs);
|
return lhs == basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5121,7 +5146,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_eq/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) == rhs;
|
return basic_json(lhs) == rhs;
|
||||||
}
|
}
|
||||||
@@ -5137,7 +5162,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs != basic_json(rhs);
|
return lhs != basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5146,7 +5171,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_ne/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) != rhs;
|
return basic_json(lhs) != rhs;
|
||||||
}
|
}
|
||||||
@@ -5166,7 +5191,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs < basic_json(rhs);
|
return lhs < basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5175,7 +5200,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_lt/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) < rhs;
|
return basic_json(lhs) < rhs;
|
||||||
}
|
}
|
||||||
@@ -5195,7 +5220,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs <= basic_json(rhs);
|
return lhs <= basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5204,7 +5229,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_le/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) <= rhs;
|
return basic_json(lhs) <= rhs;
|
||||||
}
|
}
|
||||||
@@ -5225,7 +5250,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs > basic_json(rhs);
|
return lhs > basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5234,7 +5259,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_gt/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) > rhs;
|
return basic_json(lhs) > rhs;
|
||||||
}
|
}
|
||||||
@@ -5254,7 +5279,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs >= basic_json(rhs);
|
return lhs >= basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5263,7 +5288,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_ge/
|
||||||
template<typename ScalarType, typename std::enable_if<
|
template<typename ScalarType, typename std::enable_if<
|
||||||
std::is_scalar<ScalarType>::value, int>::type = 0>
|
std::is_scalar<ScalarType>::value, int>::type = 0>
|
||||||
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) >= rhs;
|
return basic_json(lhs) >= rhs;
|
||||||
}
|
}
|
||||||
@@ -5299,6 +5324,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
// the deleted version is a function template after the class, because
|
||||||
|
// GCC < 5 and Clang < 10 reject deleted friend functions in class templates
|
||||||
/// @brief serialize to stream
|
/// @brief serialize to stream
|
||||||
/// @sa https://json.nlohmann.me/api/operator_ltlt/
|
/// @sa https://json.nlohmann.me/api/operator_ltlt/
|
||||||
/// @deprecated This function is deprecated since 3.0.0 and will be removed in
|
/// @deprecated This function is deprecated since 3.0.0 and will be removed in
|
||||||
@@ -5310,6 +5338,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
{
|
{
|
||||||
return o << j;
|
return o << j;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif // JSON_NO_IO
|
#endif // JSON_NO_IO
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -5361,12 +5390,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
const bool allow_exceptions = true,
|
const bool allow_exceptions = true,
|
||||||
const bool ignore_comments = false,
|
const bool ignore_comments = false,
|
||||||
const bool ignore_trailing_commas = false)
|
const bool ignore_trailing_commas = false)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
auto p = parser(i.get(), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas);
|
auto p = parser(i.get(), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas);
|
||||||
p.parse(true, result);
|
p.parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief check if the input is valid JSON
|
/// @brief check if the input is valid JSON
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/accept/
|
/// @sa https://json.nlohmann.me/api/basic_json/accept/
|
||||||
@@ -5396,9 +5429,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
static bool accept(detail::span_input_adapter&& i,
|
static bool accept(detail::span_input_adapter&& i,
|
||||||
const bool ignore_comments = false,
|
const bool ignore_comments = false,
|
||||||
const bool ignore_trailing_commas = false)
|
const bool ignore_trailing_commas = false)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return parser(i.get(), nullptr, false, ignore_comments, ignore_trailing_commas, true).accept(true);
|
return parser(i.get(), nullptr, false, ignore_comments, ignore_trailing_commas, true).accept(true);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief generate SAX events
|
/// @brief generate SAX events
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
|
/// @sa https://json.nlohmann.me/api/basic_json/sax_parse/
|
||||||
@@ -5459,6 +5496,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool ignore_comments = false,
|
const bool ignore_comments = false,
|
||||||
const bool ignore_trailing_commas = false)
|
const bool ignore_trailing_commas = false)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
auto ia = i.get();
|
auto ia = i.get();
|
||||||
return format == input_format_t::json
|
return format == input_format_t::json
|
||||||
@@ -5467,10 +5507,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
|
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
|
||||||
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(sax, strict);
|
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(sax, strict);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
#ifndef JSON_NO_IO
|
#ifndef JSON_NO_IO
|
||||||
|
#if !JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
// the deleted version is a function template after the class, because
|
||||||
|
// GCC < 5 and Clang < 10 reject deleted friend functions in class templates
|
||||||
/// @brief deserialize from stream
|
/// @brief deserialize from stream
|
||||||
/// @sa https://json.nlohmann.me/api/operator_gtgt/
|
/// @sa https://json.nlohmann.me/api/operator_gtgt/
|
||||||
/// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in
|
/// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in
|
||||||
@@ -5482,6 +5526,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
{
|
{
|
||||||
return operator>>(i, j);
|
return operator>>(i, j);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief deserialize from stream
|
/// @brief deserialize from stream
|
||||||
/// @sa https://json.nlohmann.me/api/operator_gtgt/
|
/// @sa https://json.nlohmann.me/api/operator_gtgt/
|
||||||
@@ -5829,9 +5874,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true,
|
const bool allow_exceptions = true,
|
||||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
|
return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
|
||||||
@@ -5839,9 +5888,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true,
|
const bool allow_exceptions = true,
|
||||||
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_binary_impl(i.get(), input_format_t::cbor, strict, allow_exceptions, error_handler_t::keep, tag_handler);
|
return from_binary_impl(i.get(), input_format_t::cbor, strict, allow_exceptions, error_handler_t::keep, tag_handler);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief create a JSON value from an input in MessagePack format
|
/// @brief create a JSON value from an input in MessagePack format
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
|
/// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/
|
||||||
@@ -5874,18 +5927,26 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
static basic_json from_msgpack(const T* ptr, std::size_t len,
|
static basic_json from_msgpack(const T* ptr, std::size_t len,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
|
return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
|
||||||
static basic_json from_msgpack(detail::span_input_adapter&& i,
|
static basic_json from_msgpack(detail::span_input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_binary_impl(i.get(), input_format_t::msgpack, strict, allow_exceptions);
|
return from_binary_impl(i.get(), input_format_t::msgpack, strict, allow_exceptions);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief create a JSON value from an input in UBJSON format
|
/// @brief create a JSON value from an input in UBJSON format
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
|
/// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/
|
||||||
@@ -5918,18 +5979,26 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
static basic_json from_ubjson(const T* ptr, std::size_t len,
|
static basic_json from_ubjson(const T* ptr, std::size_t len,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
|
return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
|
||||||
static basic_json from_ubjson(detail::span_input_adapter&& i,
|
static basic_json from_ubjson(detail::span_input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_binary_impl(i.get(), input_format_t::ubjson, strict, allow_exceptions);
|
return from_binary_impl(i.get(), input_format_t::ubjson, strict, allow_exceptions);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief create a JSON value from an input in BJData format
|
/// @brief create a JSON value from an input in BJData format
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
|
/// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/
|
||||||
@@ -5956,6 +6025,20 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::bjdata, strict, allow_exceptions, error_handler);
|
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::bjdata, strict, allow_exceptions, error_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.13.0, from_bjdata(ptr, ptr + len))
|
||||||
|
static basic_json from_bjdata(const T* ptr, std::size_t len,
|
||||||
|
const bool strict = true,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
return from_bjdata(ptr, ptr + len, strict, allow_exceptions);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief create a JSON value from an input in BON8 format
|
/// @brief create a JSON value from an input in BON8 format
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/from_bon8/
|
/// @sa https://json.nlohmann.me/api/basic_json/from_bon8/
|
||||||
template<typename InputType>
|
template<typename InputType>
|
||||||
@@ -5979,6 +6062,20 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::bon8, strict, allow_exceptions);
|
return from_binary_impl(detail::input_adapter(std::move(first), std::move(last)), input_format_t::bon8, strict, allow_exceptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
|
JSON_HEDLEY_DEPRECATED_FOR(3.13.0, from_bon8(ptr, ptr + len))
|
||||||
|
static basic_json from_bon8(const T* ptr, std::size_t len,
|
||||||
|
const bool strict = true,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
return from_bon8(ptr, ptr + len, strict, allow_exceptions);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief create a JSON value from an input in BSON format
|
/// @brief create a JSON value from an input in BSON format
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/from_bson/
|
/// @sa https://json.nlohmann.me/api/basic_json/from_bson/
|
||||||
template<typename InputType>
|
template<typename InputType>
|
||||||
@@ -6010,18 +6107,26 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
static basic_json from_bson(const T* ptr, std::size_t len,
|
static basic_json from_bson(const T* ptr, std::size_t len,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_bson(ptr, ptr + len, strict, allow_exceptions);
|
return from_bson(ptr, ptr + len, strict, allow_exceptions);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
|
||||||
static basic_json from_bson(detail::span_input_adapter&& i,
|
static basic_json from_bson(detail::span_input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return from_binary_impl(i.get(), input_format_t::bson, strict, allow_exceptions);
|
return from_binary_impl(i.get(), input_format_t::bson, strict, allow_exceptions);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
@@ -6041,9 +6146,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||||
reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
|
reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return ptr.get_unchecked(this);
|
return ptr.get_unchecked(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief access specified element via JSON Pointer
|
/// @brief access specified element via JSON Pointer
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
|
||||||
@@ -6055,9 +6164,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||||
const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return ptr.get_unchecked(this);
|
return ptr.get_unchecked(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief access specified element via JSON Pointer
|
/// @brief access specified element via JSON Pointer
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/at/
|
/// @sa https://json.nlohmann.me/api/basic_json/at/
|
||||||
@@ -6069,9 +6182,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||||
reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
|
reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return ptr.get_checked(this);
|
return ptr.get_checked(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief access specified element via JSON Pointer
|
/// @brief access specified element via JSON Pointer
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/at/
|
/// @sa https://json.nlohmann.me/api/basic_json/at/
|
||||||
@@ -6083,9 +6200,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||||
const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
= delete;
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
return ptr.get_checked(this);
|
return ptr.get_checked(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief return flattened JSON value
|
/// @brief return flattened JSON value
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/flatten/
|
/// @sa https://json.nlohmann.me/api/basic_json/flatten/
|
||||||
@@ -7062,6 +7183,18 @@ std::string format_as(const NLOHMANN_BASIC_JSON_TPL& j)
|
|||||||
return j.dump();
|
return j.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if JSON_DELETE_DEPRECATED_FUNCTIONS && !defined(JSON_NO_IO)
|
||||||
|
/// @brief serialize to stream (deleted; use operator<<(std::ostream&, const basic_json&))
|
||||||
|
/// @sa https://json.nlohmann.me/api/operator_ltlt/
|
||||||
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
|
std::ostream& operator>>(const NLOHMANN_BASIC_JSON_TPL& j, std::ostream& o) = delete;
|
||||||
|
|
||||||
|
/// @brief deserialize from stream (deleted; use operator>>(std::istream&, basic_json&))
|
||||||
|
/// @sa https://json.nlohmann.me/api/operator_gtgt/
|
||||||
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
|
std::istream& operator<<(NLOHMANN_BASIC_JSON_TPL& j, std::istream& i) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+586
-231
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,10 @@
|
|||||||
#define JSON_STRICT_BINARY_UTF8 0
|
#define JSON_STRICT_BINARY_UTF8 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
|
||||||
#else
|
#else
|
||||||
@@ -109,14 +113,20 @@
|
|||||||
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8
|
#define NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS _ekmo
|
||||||
|
#else
|
||||||
|
#define NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#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) json_abi ## a ## b ## c ## d ## e ## f ## g
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h) json_abi ## a ## b ## c ## d ## e ## f ## g ## h
|
||||||
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g) \
|
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c, d, e, f, g, h) \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g)
|
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c, d, e, f, g, h)
|
||||||
|
|
||||||
#define NLOHMANN_JSON_ABI_TAGS \
|
#define NLOHMANN_JSON_ABI_TAGS \
|
||||||
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
|
||||||
@@ -126,7 +136,8 @@
|
|||||||
NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS, \
|
NLOHMANN_JSON_ABI_TAG_BRACE_INIT_COPY_SEMANTICS, \
|
||||||
NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION, \
|
NLOHMANN_JSON_ABI_TAG_PRECISE_STREAM_POSITION, \
|
||||||
NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING, \
|
NLOHMANN_JSON_ABI_TAG_STRICT_NUL_HANDLING, \
|
||||||
NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8)
|
NLOHMANN_JSON_ABI_TAG_STRICT_BINARY_UTF8, \
|
||||||
|
NLOHMANN_JSON_ABI_TAG_OBJECTS_FOR_ENUM_KEYED_MAPS)
|
||||||
|
|
||||||
// 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) \
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ TEST_CASE("default namespace")
|
|||||||
expected += "_sbu8";
|
expected += "_sbu8";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
expected += "_ekmo";
|
||||||
|
#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";
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ TEST_CASE("default namespace without version component")
|
|||||||
expected += "_sbu8";
|
expected += "_sbu8";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
expected += "_ekmo";
|
||||||
|
#endif
|
||||||
|
|
||||||
expected += "::basic_json";
|
expected += "::basic_json";
|
||||||
|
|
||||||
// fallback for Clang
|
// fallback for Clang
|
||||||
|
|||||||
@@ -521,6 +521,10 @@ struct countdown_allocator : std::allocator<T>
|
|||||||
|
|
||||||
TEST_CASE("converting a deeply nested value from another specialization fails cleanly (#5650)")
|
TEST_CASE("converting a deeply nested value from another specialization fails cleanly (#5650)")
|
||||||
{
|
{
|
||||||
|
// MSVC 2015's debug STL constructs the containers' debug proxies through
|
||||||
|
// the allocator in noexcept constructors, so a failing construction crashes
|
||||||
|
// the program there instead of throwing std::bad_alloc. Nothing to check.
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER < 1910 && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL > 0)
|
||||||
using countdown_json = nlohmann::basic_json<std::map,
|
using countdown_json = nlohmann::basic_json<std::map,
|
||||||
std::vector,
|
std::vector,
|
||||||
std::string,
|
std::string,
|
||||||
@@ -558,6 +562,7 @@ TEST_CASE("converting a deeply nested value from another specialization fails cl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECK(failures > 0);
|
CHECK(failures > 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|||||||
@@ -11,7 +11,12 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
|
||||||
TEST_CASE("Binary Formats" * doctest::skip())
|
TEST_CASE("Binary Formats" * doctest::skip())
|
||||||
@@ -224,3 +229,139 @@ TEST_CASE("Binary Formats" * doctest::skip())
|
|||||||
CHECK((100.0 * double(ubjson_3_size) / double(json_size)) == Approx(89.450));
|
CHECK((100.0 * double(ubjson_3_size) / double(json_size)) == Approx(89.450));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// the binary formats as function pointers for "Binary formats with narrow number types";
|
||||||
|
// named functions rather than lambdas, because clang 3.5 cannot convert a lambda
|
||||||
|
// to a function pointer in the braced initializer of the format table
|
||||||
|
using narrow_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int32_t, std::uint32_t, float>;
|
||||||
|
using bytes = std::vector<std::uint8_t>;
|
||||||
|
|
||||||
|
bytes encode_cbor(const json& j)
|
||||||
|
{
|
||||||
|
return json::to_cbor(j);
|
||||||
|
}
|
||||||
|
narrow_json decode_cbor(const bytes& v, bool allow_exceptions)
|
||||||
|
{
|
||||||
|
return narrow_json::from_cbor(v, true, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes encode_msgpack(const json& j)
|
||||||
|
{
|
||||||
|
return json::to_msgpack(j);
|
||||||
|
}
|
||||||
|
narrow_json decode_msgpack(const bytes& v, bool allow_exceptions)
|
||||||
|
{
|
||||||
|
return narrow_json::from_msgpack(v, true, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes encode_ubjson(const json& j)
|
||||||
|
{
|
||||||
|
return json::to_ubjson(j);
|
||||||
|
}
|
||||||
|
narrow_json decode_ubjson(const bytes& v, bool allow_exceptions)
|
||||||
|
{
|
||||||
|
return narrow_json::from_ubjson(v, true, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes encode_bjdata(const json& j)
|
||||||
|
{
|
||||||
|
return json::to_bjdata(j);
|
||||||
|
}
|
||||||
|
narrow_json decode_bjdata(const bytes& v, bool allow_exceptions)
|
||||||
|
{
|
||||||
|
return narrow_json::from_bjdata(v, true, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BSON can only store numbers as object members
|
||||||
|
bytes encode_bson(const json& j)
|
||||||
|
{
|
||||||
|
return json::to_bson(json{{"a", j}});
|
||||||
|
}
|
||||||
|
narrow_json decode_bson(const bytes& v, bool allow_exceptions)
|
||||||
|
{
|
||||||
|
const auto result = narrow_json::from_bson(v, true, allow_exceptions);
|
||||||
|
return result.is_discarded() ? result : result.at("a");
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes encode_bon8(const json& j)
|
||||||
|
{
|
||||||
|
return json::to_bon8(j);
|
||||||
|
}
|
||||||
|
narrow_json decode_bon8(const bytes& v, bool allow_exceptions)
|
||||||
|
{
|
||||||
|
return narrow_json::from_bon8(v, true, allow_exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("Binary formats with narrow number types")
|
||||||
|
{
|
||||||
|
// Numbers that do not fit the number types are handled like the lexer
|
||||||
|
// handles them in JSON text: an integer that fits neither integer type is
|
||||||
|
// stored as a floating-point number, and a finite floating-point number
|
||||||
|
// that overflows number_float_t is rejected with out_of_range.406.
|
||||||
|
struct binary_format
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
bytes (*encode)(const json&);
|
||||||
|
narrow_json (*decode)(const bytes&, bool);
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<binary_format> formats =
|
||||||
|
{
|
||||||
|
{"CBOR", encode_cbor, decode_cbor},
|
||||||
|
{"MessagePack", encode_msgpack, decode_msgpack},
|
||||||
|
{"UBJSON", encode_ubjson, decode_ubjson},
|
||||||
|
{"BJData", encode_bjdata, decode_bjdata},
|
||||||
|
{"BSON", encode_bson, decode_bson},
|
||||||
|
{"BON8", encode_bon8, decode_bon8},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& format : formats)
|
||||||
|
{
|
||||||
|
const std::string name = format.name;
|
||||||
|
INFO("format := ", name);
|
||||||
|
const auto roundtrip = [&format](const json & j)
|
||||||
|
{
|
||||||
|
return format.decode(format.encode(j), true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// integers that fit keep their type
|
||||||
|
CHECK(roundtrip(json(-5)).is_number_integer());
|
||||||
|
CHECK(roundtrip(json(-5)).get<std::int32_t>() == -5);
|
||||||
|
CHECK(roundtrip(json(3000000000u)).is_number_unsigned());
|
||||||
|
CHECK(roundtrip(json(3000000000u)).get<std::uint32_t>() == 3000000000u);
|
||||||
|
|
||||||
|
// integers that fit neither integer type are stored as float
|
||||||
|
CHECK(roundtrip(json(5000000000u)).is_number_float());
|
||||||
|
CHECK(roundtrip(json(5000000000u)).get<float>() == 5000000000.0f);
|
||||||
|
if (name != "BON8") // BON8 cannot encode integers above INT64_MAX
|
||||||
|
{
|
||||||
|
CHECK(roundtrip(json(10000000000000000000u)).is_number_float());
|
||||||
|
CHECK(roundtrip(json(10000000000000000000u)).get<float>() == 10000000000000000000.0f);
|
||||||
|
}
|
||||||
|
CHECK(roundtrip(json(-3000000000LL)).is_number_float());
|
||||||
|
CHECK(roundtrip(json(-3000000000LL)).get<float>() == -3000000000.0f);
|
||||||
|
CHECK(roundtrip(json(-5000000000LL)).is_number_float());
|
||||||
|
CHECK(roundtrip(json(-5000000000LL)).get<float>() == -5000000000.0f);
|
||||||
|
|
||||||
|
// floating-point numbers that fit
|
||||||
|
CHECK(roundtrip(json(1.5)).get<float>() == 1.5f);
|
||||||
|
const auto just_above_max = std::nextafter(static_cast<double>((std::numeric_limits<float>::max)()),
|
||||||
|
std::numeric_limits<double>::infinity());
|
||||||
|
CHECK(roundtrip(json(just_above_max)).get<float>() == (std::numeric_limits<float>::max)());
|
||||||
|
|
||||||
|
// infinity and NaN are passed on
|
||||||
|
CHECK(std::isinf(roundtrip(json(std::numeric_limits<double>::infinity())).get<float>()));
|
||||||
|
CHECK(std::isnan(roundtrip(json(std::numeric_limits<double>::quiet_NaN())).get<float>()));
|
||||||
|
|
||||||
|
// finite floating-point numbers that overflow number_float_t are rejected
|
||||||
|
const std::string message = "[json.exception.out_of_range.406] syntax error while parsing " + name
|
||||||
|
+ " value: number overflow";
|
||||||
|
CHECK_THROWS_WITH_AS(roundtrip(json(1e300)), message.c_str(), narrow_json::out_of_range&);
|
||||||
|
CHECK_THROWS_WITH_AS(roundtrip(json(-1e300)), message.c_str(), narrow_json::out_of_range&);
|
||||||
|
CHECK(format.decode(format.encode(json(1e300)), false).is_discarded());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
#define JSON_TESTS_PRIVATE
|
#define JSON_TESTS_PRIVATE
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
@@ -4490,3 +4498,33 @@ TEST_CASE("BJData roundtrips" * doctest::skip())
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("issue #5648 - from_bjdata(ptr, len) must read len bytes, not treat ptr as a C string")
|
||||||
|
{
|
||||||
|
// to_bjdata() encodes the integer 0 as the two bytes 'i' 0x00 (a BJData
|
||||||
|
// type marker followed by the value byte 0x00), so the packed data
|
||||||
|
// below contains a 0x00 byte before its end.
|
||||||
|
const json j = {{"a", 0}};
|
||||||
|
const std::vector<std::uint8_t> packed = json::to_bjdata(j);
|
||||||
|
bool contains_nul = false;
|
||||||
|
for (const auto byte : packed)
|
||||||
|
{
|
||||||
|
contains_nul |= (byte == 0x00);
|
||||||
|
}
|
||||||
|
REQUIRE(contains_nul);
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
// before the fix, from_bjdata had no (ptr, len) overload, so this call
|
||||||
|
// bound to from_bjdata(InputType&&, bool strict) instead: ptr was read
|
||||||
|
// as a NUL-terminated C string (stopping at the embedded 0x00 byte), and
|
||||||
|
// len was silently converted to the strict flag. The deprecated
|
||||||
|
// overload added for this issue forwards to from_bjdata(ptr, ptr + len,
|
||||||
|
// ...) instead, like from_ubjson's deprecated (ptr, len) overload does.
|
||||||
|
json result;
|
||||||
|
CHECK_NOTHROW(result = json::from_bjdata(packed.data(), packed.size()));
|
||||||
|
CHECK(result == j);
|
||||||
|
|
||||||
|
// len must not collapse into the strict flag either
|
||||||
|
CHECK(json::from_bjdata(packed.data(), packed.size(), false) == j);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
||||||
@@ -1014,6 +1022,36 @@ TEST_CASE("BON8 roundtrips" * doctest::skip())
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("issue #5648 - from_bon8(ptr, len) must read len bytes, not treat ptr as a C string")
|
||||||
|
{
|
||||||
|
// to_bon8() encodes the integer 40 as the two bytes 0xC2 0x00 (a BON8
|
||||||
|
// lead byte followed by a continuation byte of 0x00), so the packed data
|
||||||
|
// below contains a 0x00 byte before its end.
|
||||||
|
const json j = {{"a", 40}, {"b", "x"}};
|
||||||
|
const std::vector<std::uint8_t> packed = json::to_bon8(j);
|
||||||
|
bool contains_nul = false;
|
||||||
|
for (const auto byte : packed)
|
||||||
|
{
|
||||||
|
contains_nul |= (byte == 0x00);
|
||||||
|
}
|
||||||
|
REQUIRE(contains_nul);
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
// before the fix, from_bon8 had no (ptr, len) overload, so this call
|
||||||
|
// bound to from_bon8(InputType&&, bool strict) instead: ptr was read as
|
||||||
|
// a NUL-terminated C string (stopping at the embedded 0x00 byte), and
|
||||||
|
// len was silently converted to the strict flag. The deprecated
|
||||||
|
// overload added for this issue forwards to from_bon8(ptr, ptr + len,
|
||||||
|
// ...) instead, like from_cbor's deprecated (ptr, len) overload does.
|
||||||
|
json result;
|
||||||
|
CHECK_NOTHROW(result = json::from_bon8(packed.data(), packed.size()));
|
||||||
|
CHECK(result == j);
|
||||||
|
|
||||||
|
// len must not collapse into the strict flag either
|
||||||
|
CHECK(json::from_bon8(packed.data(), packed.size(), false) == j);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
TEST_CASE("BON8 with std::byte")
|
TEST_CASE("BON8 with std::byte")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
@@ -1261,8 +1269,10 @@ TEST_CASE("BSON input that cannot be read is discarded by every overload")
|
|||||||
CHECK_THROWS_AS(_ = json::from_bson(input.begin(), input.end()), json::parse_error&);
|
CHECK_THROWS_AS(_ = json::from_bson(input.begin(), input.end()), json::parse_error&);
|
||||||
CHECK(json::from_bson(input, true, false).is_discarded());
|
CHECK(json::from_bson(input, true, false).is_discarded());
|
||||||
CHECK(json::from_bson(input.begin(), input.end(), true, false).is_discarded());
|
CHECK(json::from_bson(input.begin(), input.end(), true, false).is_discarded());
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
CHECK(json::from_bson(input.data(), input.size(), true, false).is_discarded());
|
CHECK(json::from_bson(input.data(), input.size(), true, false).is_discarded());
|
||||||
CHECK(json::from_bson({input.data(), input.size()}, true, false).is_discarded());
|
CHECK(json::from_bson({input.data(), input.size()}, true, false).is_discarded());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("BSON SAX parsing stops at every event")
|
TEST_CASE("BSON SAX parsing stops at every event")
|
||||||
@@ -1740,6 +1750,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip())
|
|||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
||||||
// parse JSON file
|
// parse JSON file
|
||||||
@@ -1754,6 +1765,7 @@ TEST_CASE("BSON roundtrips" * doctest::skip())
|
|||||||
// compare parsed JSON values
|
// compare parsed JSON values
|
||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": output to output adapters");
|
INFO_WITH_TEMP(filename + ": output to output adapters");
|
||||||
|
|||||||
+28
-14
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
@@ -2215,8 +2223,10 @@ TEST_CASE("CBOR input that cannot be read is discarded by every overload")
|
|||||||
CHECK_THROWS_AS(_ = json::from_cbor(input.begin(), input.end()), json::parse_error&);
|
CHECK_THROWS_AS(_ = json::from_cbor(input.begin(), input.end()), json::parse_error&);
|
||||||
CHECK(json::from_cbor(input, true, false).is_discarded());
|
CHECK(json::from_cbor(input, true, false).is_discarded());
|
||||||
CHECK(json::from_cbor(input.begin(), input.end(), true, false).is_discarded());
|
CHECK(json::from_cbor(input.begin(), input.end(), true, false).is_discarded());
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
CHECK(json::from_cbor(input.data(), input.size(), true, false).is_discarded());
|
CHECK(json::from_cbor(input.data(), input.size(), true, false).is_discarded());
|
||||||
CHECK(json::from_cbor({input.data(), input.size()}, true, false).is_discarded());
|
CHECK(json::from_cbor({input.data(), input.size()}, true, false).is_discarded());
|
||||||
|
#endif
|
||||||
|
|
||||||
// a string that ends early, read through iterators that are not
|
// a string that ends early, read through iterators that are not
|
||||||
// contiguous and have to be copied from one element at a time
|
// contiguous and have to be copied from one element at a time
|
||||||
@@ -2613,12 +2623,14 @@ TEST_CASE("CBOR roundtrips" * doctest::skip())
|
|||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()}));
|
CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()}));
|
||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": output to output adapters");
|
INFO_WITH_TEMP(filename + ": output to output adapters");
|
||||||
@@ -3185,7 +3197,8 @@ TEST_CASE("Tagged values")
|
|||||||
// CBOR encodes negative integers as: result = -1 - n
|
// CBOR encodes negative integers as: result = -1 - n
|
||||||
// For type 0x3B, n is an 8-byte uint64_t. Valid range for n with
|
// For type 0x3B, n is an 8-byte uint64_t. Valid range for n with
|
||||||
// the default int64_t is [0, INT64_MAX], producing results in [INT64_MIN, -1].
|
// the default int64_t is [0, INT64_MAX], producing results in [INT64_MIN, -1].
|
||||||
// When n > INT64_MAX, the result exceeds int64_t range and is rejected.
|
// When n > INT64_MAX, the result exceeds int64_t range and is stored
|
||||||
|
// as a floating-point number, as the lexer does for JSON text.
|
||||||
|
|
||||||
SECTION("n = 0 is valid (result = -1)")
|
SECTION("n = 0 is valid (result = -1)")
|
||||||
{
|
{
|
||||||
@@ -3206,33 +3219,34 @@ TEST_CASE("Tagged values")
|
|||||||
CHECK(result.get<int64_t>() == (std::numeric_limits<int64_t>::min)());
|
CHECK(result.get<int64_t>() == (std::numeric_limits<int64_t>::min)());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("n = INT64_MAX + 1 is rejected (overflow)")
|
SECTION("n = INT64_MAX + 1 is stored as float")
|
||||||
{
|
{
|
||||||
// n = INT64_MAX + 1 (0x8000000000000000)
|
// n = INT64_MAX + 1 (0x8000000000000000)
|
||||||
// result = -1 - n = -9223372036854775809, which exceeds int64_t range
|
// result = -1 - n = -9223372036854775809, which exceeds int64_t range;
|
||||||
|
// the nearest double is -9223372036854775808.0
|
||||||
const std::vector<uint8_t> input = {0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
const std::vector<uint8_t> input = {0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
json _;
|
const auto result = json::from_cbor(input);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(input),
|
CHECK(result.is_number_float());
|
||||||
"[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: negative integer overflow",
|
CHECK(result.get<double>() == -9223372036854775808.0);
|
||||||
json::parse_error);
|
CHECK(result == json::parse("-9223372036854775809"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("n = UINT64_MAX is rejected (overflow)")
|
SECTION("n = UINT64_MAX is stored as float")
|
||||||
{
|
{
|
||||||
// n = UINT64_MAX (0xFFFFFFFFFFFFFFFF)
|
// n = UINT64_MAX (0xFFFFFFFFFFFFFFFF)
|
||||||
// result = -1 - n = -18446744073709551616, which exceeds int64_t range
|
// result = -1 - n = -18446744073709551616, which exceeds int64_t range
|
||||||
const std::vector<uint8_t> input = {0x3B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
const std::vector<uint8_t> input = {0x3B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
json _;
|
const auto result = json::from_cbor(input);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_cbor(input),
|
CHECK(result.is_number_float());
|
||||||
"[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: negative integer overflow",
|
CHECK(result.get<double>() == -18446744073709551616.0);
|
||||||
json::parse_error);
|
CHECK(result == json::parse("-18446744073709551616"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("overflow with allow_exceptions=false returns discarded")
|
SECTION("overflow with allow_exceptions=false is not an error")
|
||||||
{
|
{
|
||||||
const std::vector<uint8_t> input = {0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
const std::vector<uint8_t> input = {0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
const auto result = json::from_cbor(input, true, false);
|
const auto result = json::from_cbor(input, true, false);
|
||||||
CHECK(result.is_discarded());
|
CHECK(result.is_number_float());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -191,8 +191,10 @@ TEST_CASE("value conversion")
|
|||||||
{
|
{
|
||||||
enum class bool_enum : bool { off, on };
|
enum class bool_enum : bool { off, on };
|
||||||
|
|
||||||
CHECK(json(bool_enum::off).get<bool_enum>() == bool_enum::off);
|
// the extra parentheses keep doctest from printing the enum via its
|
||||||
CHECK(json(bool_enum::on).get<bool_enum>() == bool_enum::on);
|
// underlying type, which MSVC 2015 reports as C4800
|
||||||
|
CHECK((json(bool_enum::off).get<bool_enum>() == bool_enum::off));
|
||||||
|
CHECK((json(bool_enum::on).get<bool_enum>() == bool_enum::on));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -851,7 +853,10 @@ TEST_CASE("std::optional")
|
|||||||
CHECK_THROWS_WITH_AS(json(opt), "cannot serialize throwing_to_json_type", std::runtime_error&);
|
CHECK_THROWS_WITH_AS(json(opt), "cannot serialize throwing_to_json_type", std::runtime_error&);
|
||||||
|
|
||||||
// the conversion is noexcept exactly when converting the contained value is
|
// the conversion is noexcept exactly when converting the contained value is
|
||||||
|
// (MSVC 2017 evaluates the conditional noexcept of this conversion as true)
|
||||||
|
#if !defined(_MSC_VER) || _MSC_VER >= 1920
|
||||||
static_assert(!std::is_nothrow_constructible<json, const std::optional<throwing_to_json_type>&>::value);
|
static_assert(!std::is_nothrow_constructible<json, const std::optional<throwing_to_json_type>&>::value);
|
||||||
|
#endif
|
||||||
static_assert(std::is_nothrow_constructible<json, const std::optional<int>&>::value);
|
static_assert(std::is_nothrow_constructible<json, const std::optional<int>&>::value);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,229 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | 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"
|
||||||
|
|
||||||
|
// This file tests the opt-in JSON_DELETE_DEPRECATED_FUNCTIONS, so it defines the
|
||||||
|
// macro itself instead of relying on the build configuration.
|
||||||
|
#ifdef JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
#undef JSON_DELETE_DEPRECATED_FUNCTIONS
|
||||||
|
#endif
|
||||||
|
#define JSON_DELETE_DEPRECATED_FUNCTIONS 1
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <istream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template<typename...>
|
||||||
|
struct make_void
|
||||||
|
{
|
||||||
|
using type = void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts>
|
||||||
|
using void_t = typename make_void<Ts...>::type;
|
||||||
|
|
||||||
|
// A deleted function is still found by overload resolution, but naming it in an
|
||||||
|
// unevaluated operand is ill-formed, so each of the following traits is false
|
||||||
|
// exactly if the expression selects a deleted (or no) function.
|
||||||
|
#define JSON_TEST_DETECT(name, expr) \
|
||||||
|
template<typename J, typename = void> \
|
||||||
|
struct name : std::false_type {}; \
|
||||||
|
template<typename J> \
|
||||||
|
struct name<J, void_t<decltype(expr)>> : std::true_type {}
|
||||||
|
|
||||||
|
using ptr_t = const std::uint8_t*;
|
||||||
|
|
||||||
|
JSON_TEST_DETECT(from_cbor_ptr_len, J::from_cbor(std::declval<ptr_t>(), std::declval<std::size_t>()));
|
||||||
|
JSON_TEST_DETECT(from_msgpack_ptr_len, J::from_msgpack(std::declval<ptr_t>(), std::declval<std::size_t>()));
|
||||||
|
JSON_TEST_DETECT(from_ubjson_ptr_len, J::from_ubjson(std::declval<ptr_t>(), std::declval<std::size_t>()));
|
||||||
|
JSON_TEST_DETECT(from_bjdata_ptr_len, J::from_bjdata(std::declval<ptr_t>(), std::declval<std::size_t>()));
|
||||||
|
JSON_TEST_DETECT(from_bon8_ptr_len, J::from_bon8(std::declval<ptr_t>(), std::declval<std::size_t>()));
|
||||||
|
JSON_TEST_DETECT(from_bson_ptr_len, J::from_bson(std::declval<ptr_t>(), std::declval<std::size_t>()));
|
||||||
|
|
||||||
|
JSON_TEST_DETECT(from_cbor_ptr_ptr, J::from_cbor(std::declval<ptr_t>(), std::declval<ptr_t>()));
|
||||||
|
JSON_TEST_DETECT(from_msgpack_ptr_ptr, J::from_msgpack(std::declval<ptr_t>(), std::declval<ptr_t>()));
|
||||||
|
JSON_TEST_DETECT(from_ubjson_ptr_ptr, J::from_ubjson(std::declval<ptr_t>(), std::declval<ptr_t>()));
|
||||||
|
JSON_TEST_DETECT(from_bjdata_ptr_ptr, J::from_bjdata(std::declval<ptr_t>(), std::declval<ptr_t>()));
|
||||||
|
JSON_TEST_DETECT(from_bon8_ptr_ptr, J::from_bon8(std::declval<ptr_t>(), std::declval<ptr_t>()));
|
||||||
|
JSON_TEST_DETECT(from_bson_ptr_ptr, J::from_bson(std::declval<ptr_t>(), std::declval<ptr_t>()));
|
||||||
|
|
||||||
|
JSON_TEST_DETECT(from_cbor_init_list, J::from_cbor({std::declval<ptr_t>(), std::declval<std::size_t>()}));
|
||||||
|
JSON_TEST_DETECT(from_msgpack_init_list, J::from_msgpack({std::declval<ptr_t>(), std::declval<std::size_t>()}));
|
||||||
|
JSON_TEST_DETECT(from_ubjson_init_list, J::from_ubjson({std::declval<ptr_t>(), std::declval<std::size_t>()}));
|
||||||
|
JSON_TEST_DETECT(from_bson_init_list, J::from_bson({std::declval<ptr_t>(), std::declval<std::size_t>()}));
|
||||||
|
|
||||||
|
JSON_TEST_DETECT(parse_init_list, J::parse({std::declval<ptr_t>(), std::declval<std::size_t>()}));
|
||||||
|
JSON_TEST_DETECT(accept_init_list, J::accept({std::declval<ptr_t>(), std::declval<std::size_t>()}));
|
||||||
|
JSON_TEST_DETECT(sax_parse_init_list, J::sax_parse({std::declval<ptr_t>(), std::declval<std::size_t>()}, std::declval<nlohmann::json_sax<J>*>()));
|
||||||
|
JSON_TEST_DETECT(parse_ptr_ptr, J::parse(std::declval<ptr_t>(), std::declval<ptr_t>()));
|
||||||
|
|
||||||
|
JSON_TEST_DETECT(iterator_wrapper, J::iterator_wrapper(std::declval<J&>()));
|
||||||
|
JSON_TEST_DETECT(iterator_wrapper_const, J::iterator_wrapper(std::declval<const J&>()));
|
||||||
|
JSON_TEST_DETECT(items, std::declval<J&>().items());
|
||||||
|
|
||||||
|
JSON_TEST_DETECT(json_ltlt_istream, std::declval<J&>() << std::declval<std::istream&>());
|
||||||
|
JSON_TEST_DETECT(istream_gtgt_json, std::declval<std::istream&>() >> std::declval<J&>());
|
||||||
|
JSON_TEST_DETECT(json_gtgt_ostream, std::declval<const J&>() >> std::declval<std::ostream&>());
|
||||||
|
JSON_TEST_DETECT(ostream_ltlt_json, std::declval<std::ostream&>() << std::declval<const J&>());
|
||||||
|
|
||||||
|
JSON_TEST_DETECT(ptr_eq_ptr, std::declval<const typename J::json_pointer&>() == std::declval<const typename J::json_pointer&>());
|
||||||
|
JSON_TEST_DETECT(ptr_ne_ptr, std::declval<const typename J::json_pointer&>() != std::declval<const typename J::json_pointer&>());
|
||||||
|
JSON_TEST_DETECT(ptr_eq_string, std::declval<const typename J::json_pointer&>() == std::declval<const std::string&>());
|
||||||
|
JSON_TEST_DETECT(string_eq_ptr, std::declval<const std::string&>() == std::declval<const typename J::json_pointer&>());
|
||||||
|
JSON_TEST_DETECT(ptr_eq_c_string, std::declval<const typename J::json_pointer&>() == std::declval<const char*>());
|
||||||
|
JSON_TEST_DETECT(c_string_eq_ptr, std::declval<const char*>() == std::declval<const typename J::json_pointer&>());
|
||||||
|
JSON_TEST_DETECT(ptr_ne_string, std::declval<const typename J::json_pointer&>() != std::declval<const std::string&>());
|
||||||
|
JSON_TEST_DETECT(string_ne_ptr, std::declval<const std::string&>() != std::declval<const typename J::json_pointer&>());
|
||||||
|
JSON_TEST_DETECT(ptr_to_string, std::declval<const typename J::json_pointer&>().to_string());
|
||||||
|
|
||||||
|
// json_pointer with a basic_json type as template argument
|
||||||
|
template<typename J>
|
||||||
|
using legacy_ptr_t = const nlohmann::json_pointer<J>& ;
|
||||||
|
JSON_TEST_DETECT(legacy_ptr_value, std::declval<const J&>().value(std::declval<legacy_ptr_t<J>>(), 0));
|
||||||
|
JSON_TEST_DETECT(legacy_ptr_value_rvalue, std::declval<const J&>().value(std::declval<legacy_ptr_t<J>>(), std::string()));
|
||||||
|
JSON_TEST_DETECT(legacy_ptr_contains, std::declval<const J&>().contains(std::declval<legacy_ptr_t<J>>()));
|
||||||
|
JSON_TEST_DETECT(legacy_ptr_subscript, std::declval<J&>()[std::declval<legacy_ptr_t<J>>()]);
|
||||||
|
JSON_TEST_DETECT(legacy_ptr_subscript_const, std::declval<const J&>()[std::declval<legacy_ptr_t<J>>()]);
|
||||||
|
JSON_TEST_DETECT(legacy_ptr_at, std::declval<J&>().at(std::declval<legacy_ptr_t<J>>()));
|
||||||
|
JSON_TEST_DETECT(legacy_ptr_at_const, std::declval<const J&>().at(std::declval<legacy_ptr_t<J>>()));
|
||||||
|
JSON_TEST_DETECT(ptr_value, std::declval<const J&>().value(std::declval<const typename J::json_pointer&>(), 0));
|
||||||
|
JSON_TEST_DETECT(ptr_at, std::declval<J&>().at(std::declval<const typename J::json_pointer&>()));
|
||||||
|
|
||||||
|
#undef JSON_TEST_DETECT
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("JSON_DELETE_DEPRECATED_FUNCTIONS")
|
||||||
|
{
|
||||||
|
// MSVC 2015 does not treat selecting a deleted function in decltype as a
|
||||||
|
// substitution failure, so the traits cannot tell deleted functions apart
|
||||||
|
// there; calling them still fails to compile
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER < 1910)
|
||||||
|
SECTION("from_* with a pointer and a length")
|
||||||
|
{
|
||||||
|
// the overloads are deleted rather than removed, so the length cannot
|
||||||
|
// silently bind to the strict parameter of from_*(InputType&&, bool)
|
||||||
|
CHECK_FALSE(from_cbor_ptr_len<json>::value);
|
||||||
|
CHECK_FALSE(from_msgpack_ptr_len<json>::value);
|
||||||
|
CHECK_FALSE(from_ubjson_ptr_len<json>::value);
|
||||||
|
CHECK_FALSE(from_bjdata_ptr_len<json>::value);
|
||||||
|
CHECK_FALSE(from_bon8_ptr_len<json>::value);
|
||||||
|
CHECK_FALSE(from_bson_ptr_len<json>::value);
|
||||||
|
|
||||||
|
// the replacement
|
||||||
|
CHECK(from_cbor_ptr_ptr<json>::value);
|
||||||
|
CHECK(from_msgpack_ptr_ptr<json>::value);
|
||||||
|
CHECK(from_ubjson_ptr_ptr<json>::value);
|
||||||
|
CHECK(from_bjdata_ptr_ptr<json>::value);
|
||||||
|
CHECK(from_bon8_ptr_ptr<json>::value);
|
||||||
|
CHECK(from_bson_ptr_ptr<json>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("initializer lists of a pointer and a length")
|
||||||
|
{
|
||||||
|
CHECK_FALSE(from_cbor_init_list<json>::value);
|
||||||
|
CHECK_FALSE(from_msgpack_init_list<json>::value);
|
||||||
|
CHECK_FALSE(from_ubjson_init_list<json>::value);
|
||||||
|
CHECK_FALSE(from_bson_init_list<json>::value);
|
||||||
|
CHECK_FALSE(parse_init_list<json>::value);
|
||||||
|
CHECK_FALSE(accept_init_list<json>::value);
|
||||||
|
CHECK_FALSE(sax_parse_init_list<json>::value);
|
||||||
|
|
||||||
|
// the replacement
|
||||||
|
CHECK(parse_ptr_ptr<json>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("iterator_wrapper")
|
||||||
|
{
|
||||||
|
CHECK_FALSE(iterator_wrapper<json>::value);
|
||||||
|
CHECK_FALSE(iterator_wrapper_const<json>::value);
|
||||||
|
|
||||||
|
// the replacement
|
||||||
|
CHECK(items<json>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("stream operators with reversed operands")
|
||||||
|
{
|
||||||
|
CHECK_FALSE(json_ltlt_istream<json>::value);
|
||||||
|
CHECK_FALSE(json_gtgt_ostream<json>::value);
|
||||||
|
|
||||||
|
// the replacement
|
||||||
|
CHECK(istream_gtgt_json<json>::value);
|
||||||
|
CHECK(ostream_ltlt_json<json>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("json_pointer")
|
||||||
|
{
|
||||||
|
// conversion to a string
|
||||||
|
CHECK_FALSE(std::is_constructible<std::string, json::json_pointer>::value);
|
||||||
|
CHECK_FALSE(std::is_convertible<json::json_pointer, std::string>::value);
|
||||||
|
|
||||||
|
// comparison with a string
|
||||||
|
CHECK_FALSE(ptr_eq_string<json>::value);
|
||||||
|
CHECK_FALSE(string_eq_ptr<json>::value);
|
||||||
|
CHECK_FALSE(ptr_eq_c_string<json>::value);
|
||||||
|
CHECK_FALSE(c_string_eq_ptr<json>::value);
|
||||||
|
CHECK_FALSE(ptr_ne_string<json>::value);
|
||||||
|
CHECK_FALSE(string_ne_ptr<json>::value);
|
||||||
|
|
||||||
|
// the replacement
|
||||||
|
CHECK(ptr_to_string<json>::value);
|
||||||
|
CHECK(ptr_eq_ptr<json>::value);
|
||||||
|
CHECK(ptr_ne_ptr<json>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("json_pointer with a basic_json type as template argument")
|
||||||
|
{
|
||||||
|
CHECK_FALSE(legacy_ptr_value<json>::value);
|
||||||
|
CHECK_FALSE(legacy_ptr_value_rvalue<json>::value);
|
||||||
|
CHECK_FALSE(legacy_ptr_contains<json>::value);
|
||||||
|
CHECK_FALSE(legacy_ptr_subscript<json>::value);
|
||||||
|
CHECK_FALSE(legacy_ptr_subscript_const<json>::value);
|
||||||
|
CHECK_FALSE(legacy_ptr_at<json>::value);
|
||||||
|
CHECK_FALSE(legacy_ptr_at_const<json>::value);
|
||||||
|
|
||||||
|
// the replacement
|
||||||
|
CHECK(ptr_value<json>::value);
|
||||||
|
CHECK(ptr_at<json>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SECTION("the non-deprecated functions still work")
|
||||||
|
{
|
||||||
|
const json j = {{"a", {1, 2}}};
|
||||||
|
const auto cbor = json::to_cbor(j);
|
||||||
|
CHECK(json::from_cbor(cbor.data(), cbor.data() + cbor.size()) == j);
|
||||||
|
|
||||||
|
const json::json_pointer ptr("/a/1");
|
||||||
|
CHECK(ptr == json::json_pointer("/a/1"));
|
||||||
|
CHECK(ptr.to_string() == "/a/1");
|
||||||
|
CHECK(j[ptr] == 2);
|
||||||
|
CHECK(j.at(ptr) == 2);
|
||||||
|
CHECK(j.value(ptr, 0) == 2);
|
||||||
|
CHECK(j.contains(ptr));
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
os << j;
|
||||||
|
CHECK(os.str() == R"({"a":[1,2]})");
|
||||||
|
std::istringstream is(os.str());
|
||||||
|
json parsed;
|
||||||
|
is >> parsed;
|
||||||
|
CHECK(parsed == j);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,14 @@
|
|||||||
#define JSON_TEST_STRICT_NUL_HANDLING_ENABLED 1
|
#define JSON_TEST_STRICT_NUL_HANDLING_ENABLED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
||||||
@@ -291,6 +299,7 @@ TEST_CASE("deserialization")
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
SECTION("operator<<")
|
SECTION("operator<<")
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -299,6 +308,7 @@ TEST_CASE("deserialization")
|
|||||||
j << ss;
|
j << ss;
|
||||||
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SECTION("operator>>")
|
SECTION("operator>>")
|
||||||
{
|
{
|
||||||
@@ -423,6 +433,7 @@ TEST_CASE("deserialization")
|
|||||||
CHECK_THROWS_WITH_AS(_ = json::parse(nullptr), "[json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
CHECK_THROWS_WITH_AS(_ = json::parse(nullptr), "[json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON", json::parse_error&);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
SECTION("operator<<")
|
SECTION("operator<<")
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -430,6 +441,7 @@ TEST_CASE("deserialization")
|
|||||||
json j;
|
json j;
|
||||||
CHECK_THROWS_WITH_AS(j << ss, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
CHECK_THROWS_WITH_AS(j << ss, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SECTION("operator>>")
|
SECTION("operator>>")
|
||||||
{
|
{
|
||||||
@@ -1148,9 +1160,9 @@ TEST_CASE("deserialization")
|
|||||||
{
|
{
|
||||||
std::istringstream s(bom + "123 456");
|
std::istringstream s(bom + "123 456");
|
||||||
json j;
|
json j;
|
||||||
j << s;
|
s >> j;
|
||||||
CHECK(j == 123);
|
CHECK(j == 123);
|
||||||
j << s;
|
s >> j;
|
||||||
CHECK(j == 456);
|
CHECK(j == 456);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1551,6 +1551,10 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
// count(0) used to compile and then crash instead of failing to compile
|
// count(0) used to compile and then crash instead of failing to compile
|
||||||
using nlohmann::detail::is_detected;
|
using nlohmann::detail::is_detected;
|
||||||
|
|
||||||
|
// MSVC 2015 does not treat selecting a deleted function in decltype as
|
||||||
|
// a substitution failure, so it detects the deleted overloads as
|
||||||
|
// callable; calling them still fails to compile
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER < 1910)
|
||||||
CHECK_FALSE(is_detected<can_call_find_with_0, Json&>::value);
|
CHECK_FALSE(is_detected<can_call_find_with_0, Json&>::value);
|
||||||
CHECK_FALSE(is_detected<can_call_find_with_0, const Json&>::value);
|
CHECK_FALSE(is_detected<can_call_find_with_0, const Json&>::value);
|
||||||
CHECK_FALSE(is_detected<can_call_count_with_0, Json&>::value);
|
CHECK_FALSE(is_detected<can_call_count_with_0, Json&>::value);
|
||||||
@@ -1562,6 +1566,7 @@ TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_j
|
|||||||
|
|
||||||
// another integral literal type must be rejected as well, not just int
|
// another integral literal type must be rejected as well, not just int
|
||||||
CHECK_FALSE(is_detected<can_call_contains_with_0L, Json&>::value);
|
CHECK_FALSE(is_detected<can_call_contains_with_0L, Json&>::value);
|
||||||
|
#endif
|
||||||
|
|
||||||
// the valid overloads must remain callable
|
// the valid overloads must remain callable
|
||||||
CHECK(is_detected<can_call_find, Json&, const char*>::value);
|
CHECK(is_detected<can_call_find, Json&, const char*>::value);
|
||||||
|
|||||||
@@ -0,0 +1,246 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | 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"
|
||||||
|
|
||||||
|
// skip tests if JSON_DisableEnumSerialization=ON (#4384)
|
||||||
|
#if defined(JSON_DISABLE_ENUM_SERIALIZATION) && (JSON_DISABLE_ENUM_SERIALIZATION == 1)
|
||||||
|
#define SKIP_TESTS_FOR_ENUM_SERIALIZATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This file tests the opt-in JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, so it defines
|
||||||
|
// the macro itself rather than relying on a -D flag, and runs in every build.
|
||||||
|
// The default behavior is tested in unit-enum_keyed_maps_default.cpp.
|
||||||
|
#ifdef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#undef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 1
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
using nlohmann::json;
|
||||||
|
using nlohmann::ordered_json;
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define STRINGIZE_EX(x) #x
|
||||||
|
#define STRINGIZE(x) STRINGIZE_EX(x)
|
||||||
|
|
||||||
|
// NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair
|
||||||
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
|
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// std::hash is only required for enums since C++14
|
||||||
|
struct enum_hash
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
std::size_t operator()(T t) const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// the example from #4378
|
||||||
|
enum TaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppcoreguidelines-use-enum-class)
|
||||||
|
{
|
||||||
|
TS_STOPPED,
|
||||||
|
TS_RUNNING,
|
||||||
|
TS_COMPLETED,
|
||||||
|
TS_INVALID = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
|
||||||
|
{
|
||||||
|
{TS_INVALID, nullptr},
|
||||||
|
{TS_STOPPED, "stopped"},
|
||||||
|
{TS_RUNNING, "running"},
|
||||||
|
{TS_COMPLETED, "completed"},
|
||||||
|
})
|
||||||
|
|
||||||
|
enum class color {red, green, blue}; // blue is not mapped and falls back to "red"
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(color,
|
||||||
|
{
|
||||||
|
{color::red, "red"},
|
||||||
|
{color::green, "green"},
|
||||||
|
})
|
||||||
|
|
||||||
|
enum class strict_color {red, green, blue}; // blue is not mapped
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(strict_color,
|
||||||
|
{
|
||||||
|
{strict_color::red, "red"},
|
||||||
|
{strict_color::green, "green"},
|
||||||
|
})
|
||||||
|
|
||||||
|
enum class digit {zero, one};
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(digit,
|
||||||
|
{
|
||||||
|
{digit::zero, 0},
|
||||||
|
{digit::one, 1},
|
||||||
|
})
|
||||||
|
|
||||||
|
#ifndef SKIP_TESTS_FOR_ENUM_SERIALIZATION
|
||||||
|
enum class plain {zero, one}; // serialized as integer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS")
|
||||||
|
{
|
||||||
|
SECTION("the macro is part of the ABI tag")
|
||||||
|
{
|
||||||
|
const std::string ns = STRINGIZE(NLOHMANN_JSON_NAMESPACE);
|
||||||
|
CHECK(ns.find("_ekmo") != std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("std::map (#4378)")
|
||||||
|
{
|
||||||
|
using task_map = std::map<TaskState, std::string>;
|
||||||
|
const task_map m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
||||||
|
const json j = m;
|
||||||
|
CHECK(j == json::parse(R"({"stopped":"aa","completed":"bb"})"));
|
||||||
|
CHECK(j.get<task_map>() == m);
|
||||||
|
|
||||||
|
json j2;
|
||||||
|
j2["x"] = m;
|
||||||
|
CHECK(j2.dump() == R"({"x":{"completed":"bb","stopped":"aa"}})");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("std::map with custom comparator")
|
||||||
|
{
|
||||||
|
using task_map = std::map<TaskState, int, std::greater<TaskState>>;
|
||||||
|
const task_map m = {{TS_STOPPED, 1}, {TS_RUNNING, 2}};
|
||||||
|
const json j = m;
|
||||||
|
CHECK(j == json::parse(R"({"stopped":1,"running":2})"));
|
||||||
|
CHECK(j.get<task_map>() == m);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("std::unordered_map")
|
||||||
|
{
|
||||||
|
using task_map = std::unordered_map<TaskState, int, enum_hash>;
|
||||||
|
const task_map m = {{TS_STOPPED, 1}, {TS_RUNNING, 2}};
|
||||||
|
const json j = m;
|
||||||
|
CHECK(j == json::parse(R"({"stopped":1,"running":2})"));
|
||||||
|
CHECK(j.get<task_map>() == m);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("nested maps")
|
||||||
|
{
|
||||||
|
using nested_map = std::map<color, std::map<TaskState, int>>;
|
||||||
|
const nested_map m = {{color::green, {{TS_RUNNING, 1}}}, {color::red, {}}};
|
||||||
|
const json j = m;
|
||||||
|
CHECK(j == json::parse(R"({"green":{"running":1},"red":{}})"));
|
||||||
|
CHECK(j.get<nested_map>() == m);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("ordered_json keeps the order of the map")
|
||||||
|
{
|
||||||
|
using task_map = std::map<TaskState, int>;
|
||||||
|
const task_map m = {{TS_STOPPED, 1}, {TS_RUNNING, 2}, {TS_COMPLETED, 3}};
|
||||||
|
const ordered_json j = m;
|
||||||
|
CHECK(j.dump() == R"({"stopped":1,"running":2,"completed":3})");
|
||||||
|
CHECK(j.get<task_map>() == m);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("empty map")
|
||||||
|
{
|
||||||
|
const json j = std::map<TaskState, int>();
|
||||||
|
CHECK(j.is_object());
|
||||||
|
CHECK(j.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("NLOHMANN_JSON_SERIALIZE_ENUM_STRICT")
|
||||||
|
{
|
||||||
|
using color_map = std::map<strict_color, int>;
|
||||||
|
const color_map m = {{strict_color::red, 1}, {strict_color::green, 2}};
|
||||||
|
const json j = m;
|
||||||
|
CHECK(j == json::parse(R"({"red":1,"green":2})"));
|
||||||
|
CHECK(j.get<color_map>() == m);
|
||||||
|
|
||||||
|
const color_map unmapped = {{strict_color::blue, 1}};
|
||||||
|
json _;
|
||||||
|
CHECK_THROWS_WITH_AS(_ = unmapped,
|
||||||
|
"[json.exception.out_of_range.410] enum value out of range for strict_color", json::out_of_range&);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("arrays of [key, value] pairs are still read")
|
||||||
|
{
|
||||||
|
using task_map = std::map<TaskState, int>;
|
||||||
|
const task_map m = {{TS_STOPPED, 1}};
|
||||||
|
CHECK(json::parse(R"([["stopped",1]])").get<task_map>() == m);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("other containers are not affected")
|
||||||
|
{
|
||||||
|
const std::vector<std::pair<TaskState, int>> pairs = {{TS_STOPPED, 1}};
|
||||||
|
const std::map<std::string, TaskState> string_keys = {{"a", TS_STOPPED}};
|
||||||
|
const std::map<int, int> int_keys = {{1, 2}};
|
||||||
|
CHECK(json(pairs) == json::parse(R"([["stopped",1]])"));
|
||||||
|
CHECK(json(string_keys) == json::parse(R"({"a":"stopped"})"));
|
||||||
|
CHECK(json(int_keys) == json::parse("[[1,2]]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("maps with non-unique keys are still stored as arrays of pairs")
|
||||||
|
{
|
||||||
|
const std::multimap<TaskState, int> mm = {{TS_STOPPED, 1}, {TS_STOPPED, 2}};
|
||||||
|
const std::unordered_multimap<TaskState, int, enum_hash> umm = {{TS_RUNNING, 3}, {TS_RUNNING, 3}};
|
||||||
|
CHECK(json(mm) == json::parse(R"([["stopped",1],["stopped",2]])"));
|
||||||
|
CHECK(json(umm) == json::parse(R"([["running",3],["running",3]])"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("keys that do not serialize to strings")
|
||||||
|
{
|
||||||
|
const std::map<TaskState, int> null_key = {{TS_INVALID, 1}};
|
||||||
|
const std::map<digit, int> number_key = {{digit::zero, 1}};
|
||||||
|
json j = "unchanged";
|
||||||
|
|
||||||
|
// mapped to null
|
||||||
|
CHECK_THROWS_WITH_AS(j = null_key,
|
||||||
|
"[json.exception.type_error.302] type must be string, but is null", json::type_error&);
|
||||||
|
|
||||||
|
// mapped to a number
|
||||||
|
CHECK_THROWS_WITH_AS(j = number_key,
|
||||||
|
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
||||||
|
|
||||||
|
#ifndef SKIP_TESTS_FOR_ENUM_SERIALIZATION
|
||||||
|
// enum without NLOHMANN_JSON_SERIALIZE_ENUM
|
||||||
|
const std::map<plain, int> plain_key = {{plain::zero, 1}};
|
||||||
|
CHECK_THROWS_WITH_AS(j = plain_key,
|
||||||
|
"[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CHECK(j == "unchanged");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("keys that serialize to the same string")
|
||||||
|
{
|
||||||
|
const std::map<color, int> m = {{color::red, 1}, {color::blue, 2}};
|
||||||
|
json j = "unchanged";
|
||||||
|
|
||||||
|
// color::blue is not mapped and falls back to "red"
|
||||||
|
CHECK_THROWS_WITH_AS(j = m,
|
||||||
|
"[json.exception.type_error.318] duplicate object key 'red'", json::type_error&);
|
||||||
|
|
||||||
|
CHECK(j == "unchanged");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | 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"
|
||||||
|
|
||||||
|
// This file tests maps with enum keys with the default setting of
|
||||||
|
// JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS (or whatever a -D flag sets it to).
|
||||||
|
// unit-enum_keyed_maps.cpp tests JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS=1.
|
||||||
|
// These tests are not part of unit-conversions.cpp, because that object file
|
||||||
|
// is already too big for the MinGW linker of some compilers.
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
// NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair
|
||||||
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
|
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
|
||||||
|
|
||||||
|
enum class cards {kreuz, pik, herz, karo};
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(cards,
|
||||||
|
{
|
||||||
|
{cards::kreuz, "kreuz"},
|
||||||
|
{cards::pik, "pik"},
|
||||||
|
{cards::herz, "herz"},
|
||||||
|
{cards::karo, "karo"}
|
||||||
|
})
|
||||||
|
|
||||||
|
enum TaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppcoreguidelines-use-enum-class)
|
||||||
|
{
|
||||||
|
TS_STOPPED,
|
||||||
|
TS_RUNNING,
|
||||||
|
TS_COMPLETED,
|
||||||
|
TS_INVALID = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
|
||||||
|
{
|
||||||
|
{TS_INVALID, nullptr},
|
||||||
|
{TS_STOPPED, "stopped"},
|
||||||
|
{TS_RUNNING, "running"},
|
||||||
|
{TS_COMPLETED, "completed"},
|
||||||
|
})
|
||||||
|
|
||||||
|
enum class strict_cards {kreuz, pik, herz, karo, andere}; // andere not included in mapping
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
||||||
|
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(strict_cards,
|
||||||
|
{
|
||||||
|
{strict_cards::kreuz, "kreuz"},
|
||||||
|
{strict_cards::pik, "pik"},
|
||||||
|
{strict_cards::herz, "herz"},
|
||||||
|
{strict_cards::karo, "karo"}
|
||||||
|
})
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// std::hash is only required for enums since C++14
|
||||||
|
struct enum_hash
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
std::size_t operator()(T t) const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// see unit-enum_keyed_maps.cpp for JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS=1
|
||||||
|
TEST_CASE("maps with enum keys")
|
||||||
|
{
|
||||||
|
using task_map = std::map<TaskState, std::string>;
|
||||||
|
using task_umap = std::unordered_map<TaskState, std::string, enum_hash>;
|
||||||
|
using task_gmap = std::map<TaskState, std::string, std::greater<TaskState>>;
|
||||||
|
using nested_map = std::map<cards, std::map<TaskState, int>>;
|
||||||
|
using strict_map = std::map<strict_cards, int>;
|
||||||
|
using int_map = std::map<int, int>;
|
||||||
|
using int_umap = std::unordered_map<int, int>;
|
||||||
|
|
||||||
|
const task_map m = {{TS_STOPPED, "aa"}, {TS_COMPLETED, "bb"}};
|
||||||
|
|
||||||
|
#if !JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
|
SECTION("stored as array of pairs")
|
||||||
|
{
|
||||||
|
CHECK(json(m) == json::parse(R"([["stopped","aa"],["completed","bb"]])"));
|
||||||
|
CHECK(json(task_umap {{TS_RUNNING, "cc"}}) == json::parse(R"([["running","cc"]])"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SECTION("read from array of pairs")
|
||||||
|
{
|
||||||
|
CHECK(json::parse(R"([["stopped","aa"],["completed","bb"]])").get<task_map>() == m);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("read from object (#4378)")
|
||||||
|
{
|
||||||
|
const json j = json::parse(R"({"stopped":"aa","completed":"bb"})");
|
||||||
|
CHECK(j.get<task_map>() == m);
|
||||||
|
CHECK(j.get<task_umap>() == task_umap(m.begin(), m.end()));
|
||||||
|
CHECK(j.get<task_gmap>() == task_gmap(m.begin(), m.end()));
|
||||||
|
CHECK(json::parse(R"({"kreuz":{"stopped":1}})").get<nested_map>() == nested_map {{cards::kreuz, {{TS_STOPPED, 1}}}});
|
||||||
|
CHECK(nlohmann::ordered_json::parse(R"({"stopped":"aa","completed":"bb"})").get<task_map>() == m);
|
||||||
|
|
||||||
|
// object keys go through the enum's from_json
|
||||||
|
strict_map sm;
|
||||||
|
CHECK_THROWS_WITH_AS(json::parse(R"({"what?":1})").get_to(sm),
|
||||||
|
"[json.exception.out_of_range.410] enum value out of range for strict_cards: \"what?\"", json::out_of_range&);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("objects are only read for enum keys")
|
||||||
|
{
|
||||||
|
// built rather than parsed, so that the messages do not gain a byte
|
||||||
|
// range with JSON_DIAGNOSTIC_POSITIONS
|
||||||
|
const json j = {{"1", 2}};
|
||||||
|
int_map im;
|
||||||
|
int_umap ium;
|
||||||
|
CHECK_THROWS_WITH_AS(j.get_to(im),
|
||||||
|
"[json.exception.type_error.302] type must be array, but is object", json::type_error&);
|
||||||
|
CHECK_THROWS_WITH_AS(j.get_to(ium),
|
||||||
|
"[json.exception.type_error.302] type must be array, but is object", json::type_error&);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("other types are rejected")
|
||||||
|
{
|
||||||
|
task_map tm;
|
||||||
|
CHECK_THROWS_WITH_AS(json("stopped").get_to(tm),
|
||||||
|
"[json.exception.type_error.302] type must be array, but is string", json::type_error&);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
@@ -19,6 +27,7 @@ DOCTEST_GCC_SUPPRESS_WARNING_PUSH
|
|||||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING("-Wrange-loop-construct")
|
DOCTEST_CLANG_SUPPRESS_WARNING("-Wrange-loop-construct")
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
TEST_CASE("iterator_wrapper")
|
TEST_CASE("iterator_wrapper")
|
||||||
{
|
{
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
@@ -715,6 +724,7 @@ TEST_CASE("iterator_wrapper")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE("items()")
|
TEST_CASE("items()")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
#define JSON_TESTS_PRIVATE
|
#define JSON_TESTS_PRIVATE
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
||||||
@@ -564,7 +572,9 @@ TEST_CASE("JSON pointers")
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << ptr;
|
ss << ptr;
|
||||||
CHECK(ptr.to_string() == ptr_str);
|
CHECK(ptr.to_string() == ptr_str);
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
CHECK(std::string(ptr) == ptr_str);
|
CHECK(std::string(ptr) == ptr_str);
|
||||||
|
#endif
|
||||||
CHECK(ss.str() == ptr_str);
|
CHECK(ss.str() == ptr_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -744,8 +754,6 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
SECTION("equality comparison")
|
SECTION("equality comparison")
|
||||||
{
|
{
|
||||||
const char* ptr_cpstring = "/foo/bar";
|
|
||||||
const char ptr_castring[] = "/foo/bar"; // NOLINT(misc-const-correctness,hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays)
|
|
||||||
std::string ptr_string{"/foo/bar"};
|
std::string ptr_string{"/foo/bar"};
|
||||||
auto ptr1 = json::json_pointer(ptr_string);
|
auto ptr1 = json::json_pointer(ptr_string);
|
||||||
auto ptr2 = json::json_pointer(ptr_string);
|
auto ptr2 = json::json_pointer(ptr_string);
|
||||||
@@ -755,6 +763,12 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
CHECK(ptr1 == ptr2);
|
CHECK(ptr1 == ptr2);
|
||||||
|
|
||||||
|
CHECK_FALSE(ptr1 != ptr2);
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
const char* ptr_cpstring = "/foo/bar";
|
||||||
|
const char ptr_castring[] = "/foo/bar"; // NOLINT(misc-const-correctness,hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays)
|
||||||
|
|
||||||
CHECK(ptr1 == "/foo/bar");
|
CHECK(ptr1 == "/foo/bar");
|
||||||
CHECK(ptr1 == ptr_cpstring);
|
CHECK(ptr1 == ptr_cpstring);
|
||||||
CHECK(ptr1 == ptr_castring);
|
CHECK(ptr1 == ptr_castring);
|
||||||
@@ -765,8 +779,6 @@ TEST_CASE("JSON pointers")
|
|||||||
CHECK(ptr_castring == ptr1);
|
CHECK(ptr_castring == ptr1);
|
||||||
CHECK(ptr_string == ptr1);
|
CHECK(ptr_string == ptr1);
|
||||||
|
|
||||||
CHECK_FALSE(ptr1 != ptr2);
|
|
||||||
|
|
||||||
CHECK_FALSE(ptr1 != "/foo/bar");
|
CHECK_FALSE(ptr1 != "/foo/bar");
|
||||||
CHECK_FALSE(ptr1 != ptr_cpstring);
|
CHECK_FALSE(ptr1 != ptr_cpstring);
|
||||||
CHECK_FALSE(ptr1 != ptr_castring);
|
CHECK_FALSE(ptr1 != ptr_castring);
|
||||||
@@ -788,6 +800,7 @@ TEST_CASE("JSON pointers")
|
|||||||
CHECK_THROWS_WITH_AS("/~~" == ptr1,
|
CHECK_THROWS_WITH_AS("/~~" == ptr1,
|
||||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'", json::parse_error&);
|
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'", json::parse_error&);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("less-than comparison")
|
SECTION("less-than comparison")
|
||||||
@@ -839,6 +852,7 @@ TEST_CASE("JSON pointers")
|
|||||||
json_ptr_j ptr_j{ptr_string};
|
json_ptr_j ptr_j{ptr_string};
|
||||||
json_ptr_oj ptr_oj{ptr_string};
|
json_ptr_oj ptr_oj{ptr_string};
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
CHECK(j.contains(ptr));
|
CHECK(j.contains(ptr));
|
||||||
CHECK(j.contains(ptr_j));
|
CHECK(j.contains(ptr_j));
|
||||||
CHECK(j.contains(ptr_oj));
|
CHECK(j.contains(ptr_oj));
|
||||||
@@ -851,6 +865,7 @@ TEST_CASE("JSON pointers")
|
|||||||
|
|
||||||
CHECK(j.value(ptr, "x") == j.value(ptr_j, "x"));
|
CHECK(j.value(ptr, "x") == j.value(ptr_j, "x"));
|
||||||
CHECK(j.value(ptr, "x") == j.value(ptr_oj, "x"));
|
CHECK(j.value(ptr, "x") == j.value(ptr_oj, "x"));
|
||||||
|
#endif
|
||||||
|
|
||||||
CHECK(ptr == ptr_j);
|
CHECK(ptr == ptr_j);
|
||||||
CHECK(ptr == ptr_oj);
|
CHECK(ptr == ptr_oj);
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
#ifdef JSON_TEST_NO_GLOBAL_UDLS
|
||||||
@@ -1795,8 +1803,10 @@ TEST_CASE("MessagePack input that cannot be read is discarded by every overload"
|
|||||||
CHECK_THROWS_AS(_ = json::from_msgpack(input.begin(), input.end()), json::parse_error&);
|
CHECK_THROWS_AS(_ = json::from_msgpack(input.begin(), input.end()), json::parse_error&);
|
||||||
CHECK(json::from_msgpack(input, true, false).is_discarded());
|
CHECK(json::from_msgpack(input, true, false).is_discarded());
|
||||||
CHECK(json::from_msgpack(input.begin(), input.end(), true, false).is_discarded());
|
CHECK(json::from_msgpack(input.begin(), input.end(), true, false).is_discarded());
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
CHECK(json::from_msgpack(input.data(), input.size(), true, false).is_discarded());
|
CHECK(json::from_msgpack(input.data(), input.size(), true, false).is_discarded());
|
||||||
CHECK(json::from_msgpack({input.data(), input.size()}, true, false).is_discarded());
|
CHECK(json::from_msgpack({input.data(), input.size()}, true, false).is_discarded());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("MessagePack SAX parsing stops at every event")
|
TEST_CASE("MessagePack SAX parsing stops at every event")
|
||||||
@@ -2099,12 +2109,14 @@ TEST_CASE("MessagePack roundtrips" * doctest::skip())
|
|||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_msgpack({packed.data(), packed.size()}));
|
CHECK_NOTHROW(j2 = json::from_msgpack({packed.data(), packed.size()}));
|
||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": output to output adapters");
|
INFO_WITH_TEMP(filename + ": output to output adapters");
|
||||||
|
|||||||
@@ -569,7 +569,7 @@ TEST_CASE("regression tests 2")
|
|||||||
SECTION("issue #2067 - cannot serialize binary data to text JSON")
|
SECTION("issue #2067 - cannot serialize binary data to text JSON")
|
||||||
{
|
{
|
||||||
const std::array<unsigned char, 23> data = {{0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32, 0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30}};
|
const std::array<unsigned char, 23> data = {{0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32, 0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30}};
|
||||||
const json j = json::from_msgpack(data.data(), data.size());
|
const json j = json::from_msgpack(data.begin(), data.end());
|
||||||
// dump() is nodiscard; this only checks that dumping does not throw
|
// dump() is nodiscard; this only checks that dumping does not throw
|
||||||
CHECK_NOTHROW(
|
CHECK_NOTHROW(
|
||||||
utils::ignore_return_value(
|
utils::ignore_return_value(
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
@@ -48,6 +56,7 @@ TEST_CASE("serialization")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
SECTION("operator>>")
|
SECTION("operator>>")
|
||||||
{
|
{
|
||||||
SECTION("no given width")
|
SECTION("no given width")
|
||||||
@@ -79,6 +88,7 @@ TEST_CASE("serialization")
|
|||||||
"[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
"[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SECTION("dump")
|
SECTION("dump")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
|
// capture whether JSON_DELETE_DEPRECATED_FUNCTIONS was enabled on the command
|
||||||
|
// line *before* including json.hpp, since the library #undefs it once the header
|
||||||
|
// has been fully processed (see include/nlohmann/detail/macro_unscope.hpp); the
|
||||||
|
// tests of deprecated functions are skipped if these functions are deleted
|
||||||
|
#if defined(JSON_DELETE_DEPRECATED_FUNCTIONS) && (JSON_DELETE_DEPRECATED_FUNCTIONS == 1)
|
||||||
|
#define JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
@@ -2212,8 +2220,10 @@ TEST_CASE("UBJSON input that cannot be read is discarded by every overload")
|
|||||||
CHECK_THROWS_AS(_ = json::from_ubjson(input.begin(), input.end()), json::parse_error&);
|
CHECK_THROWS_AS(_ = json::from_ubjson(input.begin(), input.end()), json::parse_error&);
|
||||||
CHECK(json::from_ubjson(input, true, false).is_discarded());
|
CHECK(json::from_ubjson(input, true, false).is_discarded());
|
||||||
CHECK(json::from_ubjson(input.begin(), input.end(), true, false).is_discarded());
|
CHECK(json::from_ubjson(input.begin(), input.end(), true, false).is_discarded());
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
CHECK(json::from_ubjson(input.data(), input.size(), true, false).is_discarded());
|
CHECK(json::from_ubjson(input.data(), input.size(), true, false).is_discarded());
|
||||||
CHECK(json::from_ubjson({input.data(), input.size()}, true, false).is_discarded());
|
CHECK(json::from_ubjson({input.data(), input.size()}, true, false).is_discarded());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("UBJSON SAX parsing stops at every event")
|
TEST_CASE("UBJSON SAX parsing stops at every event")
|
||||||
@@ -2961,12 +2971,14 @@ TEST_CASE("UBJSON roundtrips" * doctest::skip())
|
|||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
INFO_WITH_TEMP(filename + ": uint8_t* and size");
|
||||||
json j2;
|
json j2;
|
||||||
CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()}));
|
CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()}));
|
||||||
CHECK(j1 == j2);
|
CHECK(j1 == j2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
INFO_WITH_TEMP(filename + ": output to output adapters");
|
INFO_WITH_TEMP(filename + ": output to output adapters");
|
||||||
|
|||||||
Reference in New Issue
Block a user