mirror of
https://github.com/nlohmann/json.git
synced 2026-10-05 22:20:30 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
daad972cdb | ||
|
|
77fccaf0e7 | ||
|
|
d0278f8983 | ||
|
|
ae43e8ded4 | ||
|
|
5185181552 | ||
|
|
13d555538b |
@@ -16,9 +16,6 @@ only_commits:
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
# The Visual Studio 2017 jobs compile everything with /std:c++17, so they
|
|
||||||
# only build the C++17 variant of each test, split into two jobs each to
|
|
||||||
# stay below AppVeyor's 60-minute limit per job.
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
configuration: Debug
|
configuration: Debug
|
||||||
platform: x86
|
platform: x86
|
||||||
@@ -37,13 +34,7 @@ environment:
|
|||||||
configuration: Release
|
configuration: Release
|
||||||
platform: x86
|
platform: x86
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
|
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2"
|
CMAKE_OPTIONS: ""
|
||||||
GENERATOR: Visual Studio 15 2017
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
|
||||||
configuration: Release
|
|
||||||
platform: x86
|
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
|
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2"
|
|
||||||
GENERATOR: Visual Studio 15 2017
|
GENERATOR: Visual Studio 15 2017
|
||||||
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||||
@@ -64,13 +55,7 @@ environment:
|
|||||||
configuration: Release
|
configuration: Release
|
||||||
platform: x64
|
platform: x64
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
|
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2"
|
CMAKE_OPTIONS: ""
|
||||||
GENERATOR: Visual Studio 15 2017
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
|
||||||
configuration: Release
|
|
||||||
platform: x64
|
|
||||||
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
|
|
||||||
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2"
|
|
||||||
GENERATOR: Visual Studio 15 2017
|
GENERATOR: Visual Studio 15 2017
|
||||||
|
|
||||||
init:
|
init:
|
||||||
@@ -81,7 +66,7 @@ install:
|
|||||||
- if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32
|
- if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32
|
||||||
|
|
||||||
before_build:
|
before_build:
|
||||||
- cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On %CMAKE_OPTIONS%
|
- cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On "%CMAKE_OPTIONS%"
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cmake --build . --config "%configuration%" --parallel 2
|
- cmake --build . --config "%configuration%" --parallel 2
|
||||||
|
|||||||
@@ -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_delete_deprecated_functions, 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_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,7 +62,6 @@ 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)
|
||||||
@@ -124,10 +123,6 @@ 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()
|
||||||
@@ -164,7 +159,6 @@ 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(
|
||||||
|
|||||||
+2
-16
@@ -249,20 +249,6 @@ 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.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -376,7 +362,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 -fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/cmake/clang_sanitizer_ignorelist.txt")
|
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")
|
||||||
|
|
||||||
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}
|
||||||
@@ -719,7 +705,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_DeleteDeprecatedFunctions)
|
JSON_StrictNulHandling JSON_StrictBinaryUTF8)
|
||||||
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})
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# 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,7 +219,6 @@ 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');
|
||||||
@@ -250,7 +249,6 @@ 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 always yields `#!cpp true`:
|
For two JSON values `source` and `target`, the following code yields always `#!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: `source` and `target` are never modified.
|
Strong guarantee: if an exception is thrown, there are no changes in the JSON value.
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
|
|||||||
@@ -120,12 +120,3 @@ 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,12 +106,3 @@ 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.
|
|
||||||
|
|||||||
@@ -61,11 +61,6 @@ header. See also the [macro overview page](../../features/macros.md).
|
|||||||
- [**JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS**](json_use_objects_for_enum_keyed_maps.md) - opt in to storing maps with enum
|
- [**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
|
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
|
||||||
|
|
||||||
- [**JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON**](json_use_legacy_discarded_value_comparison.md) -
|
- [**JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON**](json_use_legacy_discarded_value_comparison.md) -
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
# 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,4 +112,3 @@ 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 and explicit conversions"
|
??? example "Example: implicit conversion"
|
||||||
|
|
||||||
This is an example for an implicit conversion:
|
This is an example for an implicit conversion:
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ The default value is `0` (disabled — existing behavior is preserved).
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example "Example: default behavior (macro not defined)"
|
??? example "Default behavior (macro not defined)"
|
||||||
|
|
||||||
Without the macro, a map with enum keys is stored as an array of pairs:
|
Without the macro, a map with enum keys is stored as an array of pairs:
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ The default value is `0` (disabled — existing behavior is preserved).
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
??? example "Example: objects for enum-keyed maps (macro defined to 1)"
|
??? example "Objects for enum-keyed maps (macro defined to 1)"
|
||||||
|
|
||||||
With the macro, the same map is stored as an object:
|
With the macro, the same map is stored as an object:
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,6 @@ 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:
|
||||||
|
|
||||||
@@ -77,8 +75,6 @@ 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>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -88,13 +84,8 @@ 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. Defining [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) to
|
code still uses. The [migration guide](../integration/migration_guide.md#replace-deprecated-functions) shows how to
|
||||||
`1` turns these warnings into errors, as the deprecated functions are then deleted. The
|
replace each of them.
|
||||||
[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 |
|
||||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----------------------------------------------------------------------------------|
|
||||||
@@ -106,7 +97,6 @@ to the `strict` parameter.
|
|||||||
| [`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.
|
||||||
|
|
||||||
|
|||||||
@@ -23,17 +23,6 @@ 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
|
||||||
@@ -97,8 +86,7 @@ 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. This
|
value, such as the result of `std::forward_as_tuple(j)`. This lets `std::tuple` convert such tuples element-wise.
|
||||||
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).
|
||||||
|
|
||||||
|
|||||||
@@ -132,12 +132,6 @@ 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,13 +14,6 @@ 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
|
||||||
@@ -48,10 +41,8 @@ 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, and to
|
`from_msgpack`, `from_ubjson`, and `from_bson` is deprecated since 3.8.0; call `from_cbor(ptr, ptr+len)` instead of
|
||||||
[`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, len)`.
|
||||||
`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,7 +292,6 @@ 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
|
||||||
|
|||||||
@@ -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>(bool_aware_static_cast<underlying_type>(val));
|
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
|
|||||||
@@ -287,20 +287,9 @@ struct external_constructor<value_t::object>
|
|||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
// whether storing the value of a std::optional<T> cannot throw; MSVC 2017
|
|
||||||
// evaluates std::is_nothrow_assignable as true even if T's to_json throws, so
|
|
||||||
// the exception would call std::terminate (#5642)
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1920
|
|
||||||
template<typename BasicJsonType, typename T>
|
|
||||||
using is_nothrow_optional_to_json = std::false_type;
|
|
||||||
#else
|
|
||||||
template<typename BasicJsonType, typename T>
|
|
||||||
using is_nothrow_optional_to_json = std::is_nothrow_assignable<BasicJsonType&, const T&>;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T,
|
||||||
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
||||||
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(is_nothrow_optional_to_json<BasicJsonType, T>::value)
|
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(std::is_nothrow_assignable<BasicJsonType&, const T&>::value)
|
||||||
{
|
{
|
||||||
if (opt.has_value())
|
if (opt.has_value())
|
||||||
{
|
{
|
||||||
@@ -376,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, bool_aware_static_cast<underlying_type>(e));
|
external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
|
|||||||
@@ -662,11 +662,10 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the value is -1 - number, which fits into number_integer_t
|
// the value is -1 - number, which fits into number_integer_t
|
||||||
// whenever number does; the outer cast undoes the integral promotion
|
// whenever number does
|
||||||
// for number_integer_t types narrower than int
|
|
||||||
if (JSON_HEDLEY_LIKELY(value_in_range_of<number_integer_t>(number)))
|
if (JSON_HEDLEY_LIKELY(value_in_range_of<number_integer_t>(number)))
|
||||||
{
|
{
|
||||||
return sax->number_integer(conditional_static_cast<number_integer_t>(static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number)));
|
return sax->number_integer(static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number));
|
||||||
}
|
}
|
||||||
|
|
||||||
// like the lexer does for JSON text, store a value too small for
|
// like the lexer does for JSON text, store a value too small for
|
||||||
@@ -4004,8 +4003,7 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
||||||
}
|
}
|
||||||
// std::isfinite has no integer overloads in MSVC's <cmath>
|
return emit_float(number);
|
||||||
return emit_float(static_cast<long double>(number));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -4028,8 +4026,7 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
||||||
}
|
}
|
||||||
// std::isfinite has no integer overloads in MSVC's <cmath>
|
return emit_float(number);
|
||||||
return emit_float(static_cast<long double>(number));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -4040,8 +4037,7 @@ class binary_reader
|
|||||||
and NaN in the input are passed on unchanged. Integers only overflow if
|
and NaN in the input are passed on unchanged. Integers only overflow if
|
||||||
number_float_t cannot represent 2^64, e.g., a half-precision type.
|
number_float_t cannot represent 2^64, e.g., a half-precision type.
|
||||||
|
|
||||||
@tparam NumberType a floating-point type (emit_signed and emit_unsigned
|
@tparam NumberType a floating-point or integer type
|
||||||
convert integers to long double first)
|
|
||||||
@param[in] number the number
|
@param[in] number the number
|
||||||
@return whether the SAX parser accepted the value
|
@return whether the SAX parser accepted the value
|
||||||
|
|
||||||
|
|||||||
@@ -81,13 +81,9 @@ 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
|
||||||
@@ -1026,13 +1022,9 @@ 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>
|
||||||
@@ -1110,26 +1102,18 @@ 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,
|
||||||
@@ -1143,26 +1127,18 @@ 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,10 +888,6 @@
|
|||||||
#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,7 +43,6 @@
|
|||||||
#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
|
#undef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -906,21 +906,6 @@ 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>...>;
|
||||||
|
|
||||||
|
|||||||
+193
-220
@@ -612,100 +612,208 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// constructor for rvalue binary arrays (internal type)
|
/// constructor for rvalue binary arrays (internal type)
|
||||||
json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
|
json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
|
||||||
|
|
||||||
void destroy(value_t t)
|
// raw, allocation-free transfer of m_data from src to dst: no
|
||||||
|
// set_parents()/assert_invariant() (the former is O(#children) per
|
||||||
|
// call under JSON_DIAGNOSTICS, which would make the walk below
|
||||||
|
// quadratic); dst takes ownership, src is left as value_t::null.
|
||||||
|
static void take(basic_json& dst, basic_json& src) noexcept
|
||||||
|
{
|
||||||
|
dst.m_data.m_type = src.m_data.m_type;
|
||||||
|
dst.m_data.m_value = src.m_data.m_value;
|
||||||
|
src.m_data.m_type = value_t::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// true if v is not an array/object, or is an already-empty one
|
||||||
|
static bool has_no_children(const basic_json& v) noexcept
|
||||||
|
{
|
||||||
|
switch (v.m_data.m_type)
|
||||||
|
{
|
||||||
|
case value_t::array:
|
||||||
|
return v.m_data.m_value.array->empty();
|
||||||
|
case value_t::object:
|
||||||
|
return v.m_data.m_value.object->empty();
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static basic_json& last_child(basic_json& v)
|
||||||
|
{
|
||||||
|
if (v.m_data.m_type == value_t::array)
|
||||||
|
{
|
||||||
|
return v.m_data.m_value.array->back();
|
||||||
|
}
|
||||||
|
JSON_ASSERT(v.m_data.m_type == value_t::object);
|
||||||
|
return v.m_data.m_value.object->rbegin()->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// removes the last child of a non-empty array/object v; this never
|
||||||
|
// allocates, and since it is only ever called when that child is a
|
||||||
|
// scalar or an already-empty array/object, destroying it never
|
||||||
|
// recurses more than one level deep (see destroy() below)
|
||||||
|
static void pop_last_child(basic_json& v)
|
||||||
|
{
|
||||||
|
if (v.m_data.m_type == value_t::array)
|
||||||
|
{
|
||||||
|
v.m_data.m_value.array->pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JSON_ASSERT(v.m_data.m_type == value_t::object);
|
||||||
|
// erase() needs a forward iterator, so std::prev(end()) is
|
||||||
|
// used here rather than rbegin() (see last_child() above)
|
||||||
|
v.m_data.m_value.object->erase(std::prev(v.m_data.m_value.object->end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// deallocates the (already empty) array/object held by v; this is
|
||||||
|
// the same allocator-based free the old recursive implementation
|
||||||
|
// used, just factored out so every level of the walk in destroy()
|
||||||
|
// can share it
|
||||||
|
static void free_container(basic_json& v) noexcept
|
||||||
|
{
|
||||||
|
if (v.m_data.m_type == value_t::array)
|
||||||
|
{
|
||||||
|
JSON_ASSERT(v.m_data.m_value.array->empty());
|
||||||
|
AllocatorType<array_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, v.m_data.m_value.array);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, v.m_data.m_value.array, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JSON_ASSERT(v.m_data.m_type == value_t::object);
|
||||||
|
JSON_ASSERT(v.m_data.m_value.object->empty());
|
||||||
|
AllocatorType<object_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, v.m_data.m_value.object);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, v.m_data.m_value.object, 1);
|
||||||
|
}
|
||||||
|
v.m_data.m_type = value_t::null; // avoid a double free if v is later destructed
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_string() noexcept
|
||||||
|
{
|
||||||
|
if (string == nullptr)
|
||||||
|
{
|
||||||
|
// not initialized (e.g., due to exception in the ctor)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AllocatorType<string_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_binary() noexcept
|
||||||
|
{
|
||||||
|
if (binary == nullptr)
|
||||||
|
{
|
||||||
|
// not initialized (e.g., due to exception in the ctor)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AllocatorType<binary_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// t must be value_t::array or value_t::object
|
||||||
|
void destroy_container(value_t t) noexcept
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(t == value_t::object && object == nullptr) ||
|
(t == value_t::object && object == nullptr) ||
|
||||||
(t == value_t::array && array == nullptr) ||
|
(t == value_t::array && array == nullptr)
|
||||||
(t == value_t::string && string == nullptr) ||
|
|
||||||
(t == value_t::binary && binary == nullptr)
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// not initialized (e.g., due to exception in the ctor)
|
// not initialized (e.g., due to exception in the ctor)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (t == value_t::array || t == value_t::object)
|
|
||||||
|
// Destroy the tree without recursing per nesting level and
|
||||||
|
// without any heap allocation: a heap-allocated flattening
|
||||||
|
// stack (the previous implementation) can itself throw
|
||||||
|
// bad_alloc, which would escape this noexcept destructor and
|
||||||
|
// terminate the program (#5135).
|
||||||
|
//
|
||||||
|
// Instead, walk down the "last child" chain, reversing links
|
||||||
|
// as we go: cur is the container currently being emptied,
|
||||||
|
// and prev is its parent (value_t::null when there is none).
|
||||||
|
// Each parent's last child slot doubles as storage for that
|
||||||
|
// parent's own parent link while we are below it, so no
|
||||||
|
// extra memory is needed. We only ever remove a child once
|
||||||
|
// it is a scalar or an empty array/object, which neither
|
||||||
|
// allocates nor recurses more than one level deep.
|
||||||
|
//
|
||||||
|
// This json_value is not itself a basic_json, so the
|
||||||
|
// top-level container is first moved into a local stand-in
|
||||||
|
// ("cur"); a default-constructed basic_json has a null
|
||||||
|
// pointer in its m_value (see data::m_value's initializer),
|
||||||
|
// so swapping it with *this leaves this union's own pointer
|
||||||
|
// null, and it is never looked at or freed a second time.
|
||||||
|
basic_json cur;
|
||||||
|
cur.m_data.m_type = t;
|
||||||
|
using std::swap;
|
||||||
|
swap(cur.m_data.m_value, *this);
|
||||||
|
|
||||||
|
basic_json prev; // value_t::null: no parent
|
||||||
|
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
// flatten the current json_value to a heap-allocated stack
|
if (has_no_children(cur))
|
||||||
std::vector<basic_json> stack;
|
|
||||||
|
|
||||||
// move the top-level items to stack
|
|
||||||
if (t == value_t::array)
|
|
||||||
{
|
{
|
||||||
stack.reserve(array->size());
|
if (prev.m_data.m_type == value_t::null)
|
||||||
std::move(array->begin(), array->end(), std::back_inserter(stack));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stack.reserve(object->size());
|
|
||||||
for (auto&& it : *object)
|
|
||||||
{
|
{
|
||||||
stack.push_back(std::move(it.second));
|
free_container(cur);
|
||||||
}
|
return; // back at the top with nothing left to do
|
||||||
}
|
|
||||||
|
|
||||||
while (!stack.empty())
|
|
||||||
{
|
|
||||||
// move the last item to a local variable to be processed
|
|
||||||
basic_json current_item(std::move(stack.back()));
|
|
||||||
stack.pop_back();
|
|
||||||
|
|
||||||
// if current_item is array/object, move
|
|
||||||
// its children to the stack to be processed later
|
|
||||||
if (current_item.is_array())
|
|
||||||
{
|
|
||||||
std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
|
|
||||||
|
|
||||||
current_item.m_data.m_value.array->clear();
|
|
||||||
}
|
|
||||||
else if (current_item.is_object())
|
|
||||||
{
|
|
||||||
for (auto&& it : *current_item.m_data.m_value.object)
|
|
||||||
{
|
|
||||||
stack.push_back(std::move(it.second));
|
|
||||||
}
|
|
||||||
|
|
||||||
current_item.m_data.m_value.object->clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// it's now safe that current_item gets destructed
|
// ascend: detach the grandparent link from prev's
|
||||||
// since it doesn't have any children
|
// last slot, drop that (now null) slot, free cur
|
||||||
|
// (it is empty), then move up one level
|
||||||
|
basic_json gp;
|
||||||
|
take(gp, last_child(prev));
|
||||||
|
pop_last_child(prev);
|
||||||
|
|
||||||
|
free_container(cur);
|
||||||
|
|
||||||
|
take(cur, prev);
|
||||||
|
take(prev, gp);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
basic_json& cur_last_ref = last_child(cur);
|
||||||
|
|
||||||
|
if (has_no_children(cur_last_ref))
|
||||||
|
{
|
||||||
|
// scalar, or already-empty array/object
|
||||||
|
pop_last_child(cur);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// descend into the non-empty last child, reversing the
|
||||||
|
// link: its slot takes over prev, and the child becomes
|
||||||
|
// the new cur
|
||||||
|
basic_json tmp;
|
||||||
|
take(tmp, cur_last_ref);
|
||||||
|
take(cur_last_ref, prev);
|
||||||
|
take(prev, cur);
|
||||||
|
take(cur, tmp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(value_t t)
|
||||||
|
{
|
||||||
switch (t)
|
switch (t)
|
||||||
{
|
{
|
||||||
case value_t::object:
|
|
||||||
{
|
|
||||||
AllocatorType<object_t> alloc;
|
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::array:
|
|
||||||
{
|
|
||||||
AllocatorType<array_t> alloc;
|
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
{
|
destroy_string();
|
||||||
AllocatorType<string_t> alloc;
|
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
{
|
destroy_binary();
|
||||||
AllocatorType<binary_t> alloc;
|
break;
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
|
case value_t::object:
|
||||||
|
case value_t::array:
|
||||||
|
destroy_container(t);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::null:
|
case value_t::null:
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
@@ -714,9 +822,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -3492,13 +3598,9 @@ 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 <
|
||||||
@@ -3507,13 +3609,9 @@ 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/
|
||||||
@@ -3871,13 +3969,9 @@ 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
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -3988,13 +4082,9 @@ 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/
|
||||||
@@ -4003,13 +4093,9 @@ 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/
|
||||||
@@ -5098,7 +5184,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) <= rhs;
|
return basic_json(lhs) <= rhs;
|
||||||
}
|
}
|
||||||
@@ -5107,7 +5193,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) >= rhs;
|
return basic_json(lhs) >= rhs;
|
||||||
}
|
}
|
||||||
@@ -5128,16 +5214,11 @@ 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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs == basic_json(rhs);
|
return lhs == basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5146,7 +5227,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) == rhs;
|
return basic_json(lhs) == rhs;
|
||||||
}
|
}
|
||||||
@@ -5162,7 +5243,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs != basic_json(rhs);
|
return lhs != basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5171,7 +5252,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) != rhs;
|
return basic_json(lhs) != rhs;
|
||||||
}
|
}
|
||||||
@@ -5191,7 +5272,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs < basic_json(rhs);
|
return lhs < basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5200,7 +5281,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) < rhs;
|
return basic_json(lhs) < rhs;
|
||||||
}
|
}
|
||||||
@@ -5220,7 +5301,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs <= basic_json(rhs);
|
return lhs <= basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5229,7 +5310,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) <= rhs;
|
return basic_json(lhs) <= rhs;
|
||||||
}
|
}
|
||||||
@@ -5250,7 +5331,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs > basic_json(rhs);
|
return lhs > basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5259,7 +5340,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) > rhs;
|
return basic_json(lhs) > rhs;
|
||||||
}
|
}
|
||||||
@@ -5279,7 +5360,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs >= basic_json(rhs);
|
return lhs >= basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -5288,7 +5369,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) >= rhs;
|
return basic_json(lhs) >= rhs;
|
||||||
}
|
}
|
||||||
@@ -5324,9 +5405,6 @@ 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
|
||||||
@@ -5338,7 +5416,6 @@ 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
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -5390,16 +5467,12 @@ 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/
|
||||||
@@ -5429,13 +5502,9 @@ 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/
|
||||||
@@ -5496,9 +5565,6 @@ 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
|
||||||
@@ -5507,14 +5573,10 @@ 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
|
||||||
@@ -5526,7 +5588,6 @@ 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/
|
||||||
@@ -5874,13 +5935,9 @@ 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))
|
||||||
@@ -5888,13 +5945,9 @@ 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/
|
||||||
@@ -5927,26 +5980,18 @@ 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/
|
||||||
@@ -5979,26 +6024,18 @@ 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/
|
||||||
@@ -6025,20 +6062,6 @@ 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>
|
||||||
@@ -6062,20 +6085,6 @@ 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>
|
||||||
@@ -6107,26 +6116,18 @@ 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
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
@@ -6146,13 +6147,9 @@ 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/
|
||||||
@@ -6164,13 +6161,9 @@ 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/
|
||||||
@@ -6182,13 +6175,9 @@ 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/
|
||||||
@@ -6200,13 +6189,9 @@ 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/
|
||||||
@@ -7183,18 +7168,6 @@ 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
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
|
|||||||
+201
-287
@@ -3225,10 +3225,6 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
#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
|
||||||
@@ -4905,21 +4901,6 @@ 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>...>;
|
||||||
|
|
||||||
@@ -5715,7 +5696,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>(bool_aware_static_cast<underlying_type>(val));
|
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
@@ -7081,20 +7062,9 @@ struct external_constructor<value_t::object>
|
|||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
#ifdef JSON_HAS_CPP_17
|
||||||
// whether storing the value of a std::optional<T> cannot throw; MSVC 2017
|
|
||||||
// evaluates std::is_nothrow_assignable as true even if T's to_json throws, so
|
|
||||||
// the exception would call std::terminate (#5642)
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1920
|
|
||||||
template<typename BasicJsonType, typename T>
|
|
||||||
using is_nothrow_optional_to_json = std::false_type;
|
|
||||||
#else
|
|
||||||
template<typename BasicJsonType, typename T>
|
|
||||||
using is_nothrow_optional_to_json = std::is_nothrow_assignable<BasicJsonType&, const T&>;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename BasicJsonType, typename T,
|
template<typename BasicJsonType, typename T,
|
||||||
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
||||||
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(is_nothrow_optional_to_json<BasicJsonType, T>::value)
|
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(std::is_nothrow_assignable<BasicJsonType&, const T&>::value)
|
||||||
{
|
{
|
||||||
if (opt.has_value())
|
if (opt.has_value())
|
||||||
{
|
{
|
||||||
@@ -7170,7 +7140,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, bool_aware_static_cast<underlying_type>(e));
|
external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
|
||||||
}
|
}
|
||||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||||
|
|
||||||
@@ -14379,11 +14349,10 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the value is -1 - number, which fits into number_integer_t
|
// the value is -1 - number, which fits into number_integer_t
|
||||||
// whenever number does; the outer cast undoes the integral promotion
|
// whenever number does
|
||||||
// for number_integer_t types narrower than int
|
|
||||||
if (JSON_HEDLEY_LIKELY(value_in_range_of<number_integer_t>(number)))
|
if (JSON_HEDLEY_LIKELY(value_in_range_of<number_integer_t>(number)))
|
||||||
{
|
{
|
||||||
return sax->number_integer(conditional_static_cast<number_integer_t>(static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number)));
|
return sax->number_integer(static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number));
|
||||||
}
|
}
|
||||||
|
|
||||||
// like the lexer does for JSON text, store a value too small for
|
// like the lexer does for JSON text, store a value too small for
|
||||||
@@ -17721,8 +17690,7 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
||||||
}
|
}
|
||||||
// std::isfinite has no integer overloads in MSVC's <cmath>
|
return emit_float(number);
|
||||||
return emit_float(static_cast<long double>(number));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -17745,8 +17713,7 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
return sax->number_unsigned(static_cast<number_unsigned_t>(number));
|
||||||
}
|
}
|
||||||
// std::isfinite has no integer overloads in MSVC's <cmath>
|
return emit_float(number);
|
||||||
return emit_float(static_cast<long double>(number));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -17757,8 +17724,7 @@ class binary_reader
|
|||||||
and NaN in the input are passed on unchanged. Integers only overflow if
|
and NaN in the input are passed on unchanged. Integers only overflow if
|
||||||
number_float_t cannot represent 2^64, e.g., a half-precision type.
|
number_float_t cannot represent 2^64, e.g., a half-precision type.
|
||||||
|
|
||||||
@tparam NumberType a floating-point type (emit_signed and emit_unsigned
|
@tparam NumberType a floating-point or integer type
|
||||||
convert integers to long double first)
|
|
||||||
@param[in] number the number
|
@param[in] number the number
|
||||||
@return whether the SAX parser accepted the value
|
@return whether the SAX parser accepted the value
|
||||||
|
|
||||||
@@ -19964,13 +19930,9 @@ 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
|
||||||
@@ -20909,13 +20871,9 @@ 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>
|
||||||
@@ -20993,26 +20951,18 @@ 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,
|
||||||
@@ -21026,26 +20976,18 @@ 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,
|
||||||
@@ -27792,100 +27734,208 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// constructor for rvalue binary arrays (internal type)
|
/// constructor for rvalue binary arrays (internal type)
|
||||||
json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
|
json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
|
||||||
|
|
||||||
void destroy(value_t t)
|
// raw, allocation-free transfer of m_data from src to dst: no
|
||||||
|
// set_parents()/assert_invariant() (the former is O(#children) per
|
||||||
|
// call under JSON_DIAGNOSTICS, which would make the walk below
|
||||||
|
// quadratic); dst takes ownership, src is left as value_t::null.
|
||||||
|
static void take(basic_json& dst, basic_json& src) noexcept
|
||||||
|
{
|
||||||
|
dst.m_data.m_type = src.m_data.m_type;
|
||||||
|
dst.m_data.m_value = src.m_data.m_value;
|
||||||
|
src.m_data.m_type = value_t::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// true if v is not an array/object, or is an already-empty one
|
||||||
|
static bool has_no_children(const basic_json& v) noexcept
|
||||||
|
{
|
||||||
|
switch (v.m_data.m_type)
|
||||||
|
{
|
||||||
|
case value_t::array:
|
||||||
|
return v.m_data.m_value.array->empty();
|
||||||
|
case value_t::object:
|
||||||
|
return v.m_data.m_value.object->empty();
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static basic_json& last_child(basic_json& v)
|
||||||
|
{
|
||||||
|
if (v.m_data.m_type == value_t::array)
|
||||||
|
{
|
||||||
|
return v.m_data.m_value.array->back();
|
||||||
|
}
|
||||||
|
JSON_ASSERT(v.m_data.m_type == value_t::object);
|
||||||
|
return v.m_data.m_value.object->rbegin()->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// removes the last child of a non-empty array/object v; this never
|
||||||
|
// allocates, and since it is only ever called when that child is a
|
||||||
|
// scalar or an already-empty array/object, destroying it never
|
||||||
|
// recurses more than one level deep (see destroy() below)
|
||||||
|
static void pop_last_child(basic_json& v)
|
||||||
|
{
|
||||||
|
if (v.m_data.m_type == value_t::array)
|
||||||
|
{
|
||||||
|
v.m_data.m_value.array->pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JSON_ASSERT(v.m_data.m_type == value_t::object);
|
||||||
|
// erase() needs a forward iterator, so std::prev(end()) is
|
||||||
|
// used here rather than rbegin() (see last_child() above)
|
||||||
|
v.m_data.m_value.object->erase(std::prev(v.m_data.m_value.object->end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// deallocates the (already empty) array/object held by v; this is
|
||||||
|
// the same allocator-based free the old recursive implementation
|
||||||
|
// used, just factored out so every level of the walk in destroy()
|
||||||
|
// can share it
|
||||||
|
static void free_container(basic_json& v) noexcept
|
||||||
|
{
|
||||||
|
if (v.m_data.m_type == value_t::array)
|
||||||
|
{
|
||||||
|
JSON_ASSERT(v.m_data.m_value.array->empty());
|
||||||
|
AllocatorType<array_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, v.m_data.m_value.array);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, v.m_data.m_value.array, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JSON_ASSERT(v.m_data.m_type == value_t::object);
|
||||||
|
JSON_ASSERT(v.m_data.m_value.object->empty());
|
||||||
|
AllocatorType<object_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, v.m_data.m_value.object);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, v.m_data.m_value.object, 1);
|
||||||
|
}
|
||||||
|
v.m_data.m_type = value_t::null; // avoid a double free if v is later destructed
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_string() noexcept
|
||||||
|
{
|
||||||
|
if (string == nullptr)
|
||||||
|
{
|
||||||
|
// not initialized (e.g., due to exception in the ctor)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AllocatorType<string_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_binary() noexcept
|
||||||
|
{
|
||||||
|
if (binary == nullptr)
|
||||||
|
{
|
||||||
|
// not initialized (e.g., due to exception in the ctor)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AllocatorType<binary_t> alloc;
|
||||||
|
std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
|
||||||
|
std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// t must be value_t::array or value_t::object
|
||||||
|
void destroy_container(value_t t) noexcept
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(t == value_t::object && object == nullptr) ||
|
(t == value_t::object && object == nullptr) ||
|
||||||
(t == value_t::array && array == nullptr) ||
|
(t == value_t::array && array == nullptr)
|
||||||
(t == value_t::string && string == nullptr) ||
|
|
||||||
(t == value_t::binary && binary == nullptr)
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// not initialized (e.g., due to exception in the ctor)
|
// not initialized (e.g., due to exception in the ctor)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (t == value_t::array || t == value_t::object)
|
|
||||||
|
// Destroy the tree without recursing per nesting level and
|
||||||
|
// without any heap allocation: a heap-allocated flattening
|
||||||
|
// stack (the previous implementation) can itself throw
|
||||||
|
// bad_alloc, which would escape this noexcept destructor and
|
||||||
|
// terminate the program (#5135).
|
||||||
|
//
|
||||||
|
// Instead, walk down the "last child" chain, reversing links
|
||||||
|
// as we go: cur is the container currently being emptied,
|
||||||
|
// and prev is its parent (value_t::null when there is none).
|
||||||
|
// Each parent's last child slot doubles as storage for that
|
||||||
|
// parent's own parent link while we are below it, so no
|
||||||
|
// extra memory is needed. We only ever remove a child once
|
||||||
|
// it is a scalar or an empty array/object, which neither
|
||||||
|
// allocates nor recurses more than one level deep.
|
||||||
|
//
|
||||||
|
// This json_value is not itself a basic_json, so the
|
||||||
|
// top-level container is first moved into a local stand-in
|
||||||
|
// ("cur"); a default-constructed basic_json has a null
|
||||||
|
// pointer in its m_value (see data::m_value's initializer),
|
||||||
|
// so swapping it with *this leaves this union's own pointer
|
||||||
|
// null, and it is never looked at or freed a second time.
|
||||||
|
basic_json cur;
|
||||||
|
cur.m_data.m_type = t;
|
||||||
|
using std::swap;
|
||||||
|
swap(cur.m_data.m_value, *this);
|
||||||
|
|
||||||
|
basic_json prev; // value_t::null: no parent
|
||||||
|
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
// flatten the current json_value to a heap-allocated stack
|
if (has_no_children(cur))
|
||||||
std::vector<basic_json> stack;
|
|
||||||
|
|
||||||
// move the top-level items to stack
|
|
||||||
if (t == value_t::array)
|
|
||||||
{
|
{
|
||||||
stack.reserve(array->size());
|
if (prev.m_data.m_type == value_t::null)
|
||||||
std::move(array->begin(), array->end(), std::back_inserter(stack));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stack.reserve(object->size());
|
|
||||||
for (auto&& it : *object)
|
|
||||||
{
|
{
|
||||||
stack.push_back(std::move(it.second));
|
free_container(cur);
|
||||||
}
|
return; // back at the top with nothing left to do
|
||||||
}
|
|
||||||
|
|
||||||
while (!stack.empty())
|
|
||||||
{
|
|
||||||
// move the last item to a local variable to be processed
|
|
||||||
basic_json current_item(std::move(stack.back()));
|
|
||||||
stack.pop_back();
|
|
||||||
|
|
||||||
// if current_item is array/object, move
|
|
||||||
// its children to the stack to be processed later
|
|
||||||
if (current_item.is_array())
|
|
||||||
{
|
|
||||||
std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
|
|
||||||
|
|
||||||
current_item.m_data.m_value.array->clear();
|
|
||||||
}
|
|
||||||
else if (current_item.is_object())
|
|
||||||
{
|
|
||||||
for (auto&& it : *current_item.m_data.m_value.object)
|
|
||||||
{
|
|
||||||
stack.push_back(std::move(it.second));
|
|
||||||
}
|
|
||||||
|
|
||||||
current_item.m_data.m_value.object->clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// it's now safe that current_item gets destructed
|
// ascend: detach the grandparent link from prev's
|
||||||
// since it doesn't have any children
|
// last slot, drop that (now null) slot, free cur
|
||||||
|
// (it is empty), then move up one level
|
||||||
|
basic_json gp;
|
||||||
|
take(gp, last_child(prev));
|
||||||
|
pop_last_child(prev);
|
||||||
|
|
||||||
|
free_container(cur);
|
||||||
|
|
||||||
|
take(cur, prev);
|
||||||
|
take(prev, gp);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
basic_json& cur_last_ref = last_child(cur);
|
||||||
|
|
||||||
|
if (has_no_children(cur_last_ref))
|
||||||
|
{
|
||||||
|
// scalar, or already-empty array/object
|
||||||
|
pop_last_child(cur);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// descend into the non-empty last child, reversing the
|
||||||
|
// link: its slot takes over prev, and the child becomes
|
||||||
|
// the new cur
|
||||||
|
basic_json tmp;
|
||||||
|
take(tmp, cur_last_ref);
|
||||||
|
take(cur_last_ref, prev);
|
||||||
|
take(prev, cur);
|
||||||
|
take(cur, tmp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(value_t t)
|
||||||
|
{
|
||||||
switch (t)
|
switch (t)
|
||||||
{
|
{
|
||||||
case value_t::object:
|
|
||||||
{
|
|
||||||
AllocatorType<object_t> alloc;
|
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::array:
|
|
||||||
{
|
|
||||||
AllocatorType<array_t> alloc;
|
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
{
|
destroy_string();
|
||||||
AllocatorType<string_t> alloc;
|
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
{
|
destroy_binary();
|
||||||
AllocatorType<binary_t> alloc;
|
break;
|
||||||
std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
|
|
||||||
std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
|
case value_t::object:
|
||||||
|
case value_t::array:
|
||||||
|
destroy_container(t);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case value_t::null:
|
case value_t::null:
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
@@ -27894,9 +27944,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -30672,13 +30720,9 @@ 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 <
|
||||||
@@ -30687,13 +30731,9 @@ 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/
|
||||||
@@ -31051,13 +31091,9 @@ 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
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -31168,13 +31204,9 @@ 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/
|
||||||
@@ -31183,13 +31215,9 @@ 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/
|
||||||
@@ -32278,7 +32306,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) <= rhs;
|
return basic_json(lhs) <= rhs;
|
||||||
}
|
}
|
||||||
@@ -32287,7 +32315,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) >= rhs;
|
return basic_json(lhs) >= rhs;
|
||||||
}
|
}
|
||||||
@@ -32308,16 +32336,11 @@ 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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs == basic_json(rhs);
|
return lhs == basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -32326,7 +32349,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) == rhs;
|
return basic_json(lhs) == rhs;
|
||||||
}
|
}
|
||||||
@@ -32342,7 +32365,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs != basic_json(rhs);
|
return lhs != basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -32351,7 +32374,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) != rhs;
|
return basic_json(lhs) != rhs;
|
||||||
}
|
}
|
||||||
@@ -32371,7 +32394,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs < basic_json(rhs);
|
return lhs < basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -32380,7 +32403,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) < rhs;
|
return basic_json(lhs) < rhs;
|
||||||
}
|
}
|
||||||
@@ -32400,7 +32423,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs <= basic_json(rhs);
|
return lhs <= basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -32409,7 +32432,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) <= rhs;
|
return basic_json(lhs) <= rhs;
|
||||||
}
|
}
|
||||||
@@ -32430,7 +32453,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs > basic_json(rhs);
|
return lhs > basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -32439,7 +32462,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) > rhs;
|
return basic_json(lhs) > rhs;
|
||||||
}
|
}
|
||||||
@@ -32459,7 +32482,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<detail::uncvref_t<decltype(lhs)>, ScalarType>::value)
|
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return lhs >= basic_json(rhs);
|
return lhs >= basic_json(rhs);
|
||||||
}
|
}
|
||||||
@@ -32468,7 +32491,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<detail::uncvref_t<decltype(rhs)>, ScalarType>::value)
|
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value)
|
||||||
{
|
{
|
||||||
return basic_json(lhs) >= rhs;
|
return basic_json(lhs) >= rhs;
|
||||||
}
|
}
|
||||||
@@ -32504,9 +32527,6 @@ 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
|
||||||
@@ -32518,7 +32538,6 @@ 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
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -32570,16 +32589,12 @@ 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/
|
||||||
@@ -32609,13 +32624,9 @@ 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/
|
||||||
@@ -32676,9 +32687,6 @@ 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
|
||||||
@@ -32687,14 +32695,10 @@ 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
|
||||||
@@ -32706,7 +32710,6 @@ 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/
|
||||||
@@ -33054,13 +33057,9 @@ 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))
|
||||||
@@ -33068,13 +33067,9 @@ 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/
|
||||||
@@ -33107,26 +33102,18 @@ 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/
|
||||||
@@ -33159,26 +33146,18 @@ 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/
|
||||||
@@ -33205,20 +33184,6 @@ 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>
|
||||||
@@ -33242,20 +33207,6 @@ 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>
|
||||||
@@ -33287,26 +33238,18 @@ 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
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
@@ -33326,13 +33269,9 @@ 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/
|
||||||
@@ -33344,13 +33283,9 @@ 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/
|
||||||
@@ -33362,13 +33297,9 @@ 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/
|
||||||
@@ -33380,13 +33311,9 @@ 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/
|
||||||
@@ -34363,18 +34290,6 @@ 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
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
@@ -34558,7 +34473,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
|
|||||||
#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
|
#undef JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ set(JSON_SIMDUTF_VERSION 9.1.0 CACHE STRING "The simdutf version used by JSON_Te
|
|||||||
|
|
||||||
set(JSON_32bitTest AUTO CACHE STRING "Enable the 32bit unit test (ON/OFF/AUTO/ONLY).")
|
set(JSON_32bitTest AUTO CACHE STRING "Enable the 32bit unit test (ON/OFF/AUTO/ONLY).")
|
||||||
set(JSON_TestStandards "" CACHE STRING "The list of standards to test explicitly.")
|
set(JSON_TestStandards "" CACHE STRING "The list of standards to test explicitly.")
|
||||||
set(JSON_TestShard "" CACHE STRING "Build only a part of the unit tests, given as <index>/<count> (e.g. 0/2), to split them across CI jobs with a time limit.")
|
|
||||||
|
|
||||||
# using an env var, since this will also affect targets executing cmake (such as "ci_test_compiler_default")
|
# using an env var, since this will also affect targets executing cmake (such as "ci_test_compiler_default")
|
||||||
if (NOT "" STREQUAL "$ENV{JSON_FORCED_GLOBAL_COMPILE_OPTIONS}")
|
if (NOT "" STREQUAL "$ENV{JSON_FORCED_GLOBAL_COMPILE_OPTIONS}")
|
||||||
@@ -289,33 +288,6 @@ elseif(NOT json_32bit_test)
|
|||||||
list(FILTER files EXCLUDE REGEX src/unit-32bit.cpp)
|
list(FILTER files EXCLUDE REGEX src/unit-32bit.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# with JSON_TestShard=<index>/<count>, keep every <count>-th unit test file,
|
|
||||||
# starting at <index> (the glob is sorted, so the split is stable)
|
|
||||||
set(test_shard_index 0)
|
|
||||||
if(NOT "${JSON_TestShard}" STREQUAL "")
|
|
||||||
if(NOT JSON_TestShard MATCHES "^([0-9]+)/([1-9][0-9]*)$")
|
|
||||||
message(FATAL_ERROR "JSON_TestShard must be <index>/<count>, e.g. 0/2, not '${JSON_TestShard}'.")
|
|
||||||
endif()
|
|
||||||
set(test_shard_index ${CMAKE_MATCH_1})
|
|
||||||
set(test_shard_count ${CMAKE_MATCH_2})
|
|
||||||
if(NOT test_shard_index LESS test_shard_count)
|
|
||||||
message(FATAL_ERROR "JSON_TestShard: the index must be less than the count, not '${JSON_TestShard}'.")
|
|
||||||
endif()
|
|
||||||
list(LENGTH files test_file_count)
|
|
||||||
set(shard_files "")
|
|
||||||
set(file_position 0)
|
|
||||||
foreach(file ${files})
|
|
||||||
math(EXPR file_shard "${file_position} % ${test_shard_count}")
|
|
||||||
if(file_shard EQUAL test_shard_index)
|
|
||||||
list(APPEND shard_files ${file})
|
|
||||||
endif()
|
|
||||||
math(EXPR file_position "${file_position} + 1")
|
|
||||||
endforeach()
|
|
||||||
set(files ${shard_files})
|
|
||||||
list(LENGTH files shard_file_count)
|
|
||||||
message(STATUS "Test shard ${JSON_TestShard}: ${shard_file_count} of ${test_file_count} unit test files")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
foreach(file ${files})
|
foreach(file ${files})
|
||||||
json_test_add_test_for(${file} MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force})
|
json_test_add_test_for(${file} MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force})
|
||||||
endforeach()
|
endforeach()
|
||||||
@@ -333,9 +305,6 @@ if(json_32bit_test_only)
|
|||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# the following variants of single test files are only built in the first shard
|
|
||||||
if(test_shard_index EQUAL 0)
|
|
||||||
|
|
||||||
# test legacy comparison of discarded values
|
# test legacy comparison of discarded values
|
||||||
json_test_set_test_options(test-comparison_legacy
|
json_test_set_test_options(test-comparison_legacy
|
||||||
COMPILE_DEFINITIONS JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1
|
COMPILE_DEFINITIONS JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1
|
||||||
@@ -363,8 +332,6 @@ json_test_add_test_for(src/unit-diagnostic-positions.cpp
|
|||||||
MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force}
|
MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force}
|
||||||
)
|
)
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# *DO NOT* use json_test_set_test_options() below this line
|
# *DO NOT* use json_test_set_test_options() below this line
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|||||||
@@ -521,10 +521,6 @@ 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,
|
||||||
@@ -562,7 +558,6 @@ TEST_CASE("converting a deeply nested value from another specialization fails cl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECK(failures > 0);
|
CHECK(failures > 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -607,3 +602,88 @@ TEST_CASE("bad my_allocator::construct")
|
|||||||
j["test"].push_back("should not leak");
|
j["test"].push_back("should not leak");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::size_t counting_allocator_allocations = 0;
|
||||||
|
std::size_t counting_allocator_deallocations = 0;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct counting_allocator : std::allocator<T>
|
||||||
|
{
|
||||||
|
using std::allocator<T>::allocator;
|
||||||
|
|
||||||
|
T* allocate(std::size_t n)
|
||||||
|
{
|
||||||
|
++counting_allocator_allocations;
|
||||||
|
return std::allocator<T>::allocate(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
++counting_allocator_deallocations;
|
||||||
|
std::allocator<T>::deallocate(p, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
using other = counting_allocator<U>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("destructor performs no allocation, only deallocation")
|
||||||
|
{
|
||||||
|
// see https://github.com/nlohmann/json/issues/4842 and
|
||||||
|
// https://github.com/nlohmann/json/issues/5135: destroying nested
|
||||||
|
// arrays/objects used to allocate a temporary stack (first with
|
||||||
|
// std::allocator, later - after #4842 - with the provided allocator).
|
||||||
|
// Since that stack could itself throw bad_alloc from inside the
|
||||||
|
// noexcept destructor (#5135), destroy() no longer allocates anything:
|
||||||
|
// it only ever frees what is already there.
|
||||||
|
using counting_json = nlohmann::basic_json<std::map,
|
||||||
|
std::vector,
|
||||||
|
std::string,
|
||||||
|
bool,
|
||||||
|
std::int64_t,
|
||||||
|
std::uint64_t,
|
||||||
|
double,
|
||||||
|
counting_allocator>;
|
||||||
|
|
||||||
|
SECTION("array")
|
||||||
|
{
|
||||||
|
auto* j = new counting_json({1, {2, {3, 4}}, 5}); // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
const auto allocations_before = counting_allocator_allocations;
|
||||||
|
const auto deallocations_before = counting_allocator_deallocations;
|
||||||
|
delete j; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
CHECK(counting_allocator_allocations == allocations_before);
|
||||||
|
CHECK(counting_allocator_deallocations > deallocations_before);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("object")
|
||||||
|
{
|
||||||
|
auto* j = new counting_json({{"a", {{"b", {1, 2}}}}, {"c", 3}}); // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
const auto allocations_before = counting_allocator_allocations;
|
||||||
|
const auto deallocations_before = counting_allocator_deallocations;
|
||||||
|
delete j; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
CHECK(counting_allocator_allocations == allocations_before);
|
||||||
|
CHECK(counting_allocator_deallocations > deallocations_before);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("mixed tree of empty/non-empty arrays and objects")
|
||||||
|
{
|
||||||
|
auto* j = new counting_json( // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
{
|
||||||
|
{"empty_obj", counting_json::object()},
|
||||||
|
{"empty_arr", counting_json::array()},
|
||||||
|
{"nested", {{"a", counting_json::array({1, 2, counting_json::object()})}, {"b", 3}}},
|
||||||
|
{"tail", counting_json::array({counting_json::array({1}), 2, counting_json::array({3})})}
|
||||||
|
});
|
||||||
|
const auto allocations_before = counting_allocator_allocations;
|
||||||
|
const auto deallocations_before = counting_allocator_deallocations;
|
||||||
|
delete j; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
CHECK(counting_allocator_allocations == allocations_before);
|
||||||
|
CHECK(counting_allocator_deallocations > deallocations_before);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,14 +9,6 @@
|
|||||||
#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;
|
||||||
|
|
||||||
@@ -4498,33 +4490,3 @@ 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,14 +8,6 @@
|
|||||||
|
|
||||||
#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
|
||||||
@@ -1022,36 +1014,6 @@ 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,14 +8,6 @@
|
|||||||
|
|
||||||
#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;
|
||||||
|
|
||||||
@@ -1269,10 +1261,8 @@ 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")
|
||||||
@@ -1750,7 +1740,6 @@ 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
|
||||||
@@ -1765,7 +1754,6 @@ 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");
|
||||||
|
|||||||
@@ -8,14 +8,6 @@
|
|||||||
|
|
||||||
#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;
|
||||||
|
|
||||||
@@ -2223,10 +2215,8 @@ 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
|
||||||
@@ -2623,14 +2613,12 @@ 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");
|
||||||
|
|||||||
@@ -191,10 +191,8 @@ TEST_CASE("value conversion")
|
|||||||
{
|
{
|
||||||
enum class bool_enum : bool { off, on };
|
enum class bool_enum : bool { off, on };
|
||||||
|
|
||||||
// the extra parentheses keep doctest from printing the enum via its
|
CHECK(json(bool_enum::off).get<bool_enum>() == bool_enum::off);
|
||||||
// underlying type, which MSVC 2015 reports as C4800
|
CHECK(json(bool_enum::on).get<bool_enum>() == bool_enum::on);
|
||||||
CHECK((json(bool_enum::off).get<bool_enum>() == bool_enum::off));
|
|
||||||
CHECK((json(bool_enum::on).get<bool_enum>() == bool_enum::on));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -853,11 +851,8 @@ 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
|
||||||
// (except with MSVC 2017, where it is never noexcept, see to_json.hpp)
|
|
||||||
#if !defined(_MSC_VER) || defined(__clang__) || _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);
|
||||||
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,229 +0,0 @@
|
|||||||
// __ _____ _____ _____
|
|
||||||
// __| | __| | | | 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,14 +16,6 @@
|
|||||||
#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
|
||||||
@@ -299,7 +291,6 @@ TEST_CASE("deserialization")
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
|
||||||
SECTION("operator<<")
|
SECTION("operator<<")
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -308,7 +299,6 @@ 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>>")
|
||||||
{
|
{
|
||||||
@@ -433,7 +423,6 @@ 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;
|
||||||
@@ -441,7 +430,6 @@ 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>>")
|
||||||
{
|
{
|
||||||
@@ -1160,9 +1148,9 @@ TEST_CASE("deserialization")
|
|||||||
{
|
{
|
||||||
std::istringstream s(bom + "123 456");
|
std::istringstream s(bom + "123 456");
|
||||||
json j;
|
json j;
|
||||||
s >> j;
|
j << s;
|
||||||
CHECK(j == 123);
|
CHECK(j == 123);
|
||||||
s >> j;
|
j << s;
|
||||||
CHECK(j == 456);
|
CHECK(j == 456);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1551,10 +1551,6 @@ 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);
|
||||||
@@ -1566,7 +1562,6 @@ 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);
|
||||||
|
|||||||
@@ -8,14 +8,6 @@
|
|||||||
|
|
||||||
#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;
|
||||||
|
|
||||||
@@ -27,7 +19,6 @@ 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")
|
||||||
@@ -724,7 +715,6 @@ TEST_CASE("iterator_wrapper")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST_CASE("items()")
|
TEST_CASE("items()")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,14 +9,6 @@
|
|||||||
#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
|
||||||
@@ -572,9 +564,7 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -754,6 +744,8 @@ 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);
|
||||||
@@ -763,12 +755,6 @@ 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);
|
||||||
@@ -779,6 +765,8 @@ 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);
|
||||||
@@ -800,7 +788,6 @@ 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")
|
||||||
@@ -852,7 +839,6 @@ 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));
|
||||||
@@ -865,7 +851,6 @@ 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,14 +8,6 @@
|
|||||||
|
|
||||||
#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
|
||||||
@@ -1803,10 +1795,8 @@ 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")
|
||||||
@@ -2109,14 +2099,12 @@ 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");
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ using ordered_json = nlohmann::ordered_json;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <new>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -107,6 +109,84 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
|
|||||||
|
|
||||||
using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
|
using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
|
||||||
|
|
||||||
|
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// An allocator whose allocate() can be told to fail on demand, so tests can
|
||||||
|
// check that ~basic_json() tolerates - in fact, after #5135, never even
|
||||||
|
// triggers - an allocation failure. This replaces an earlier version of
|
||||||
|
// this test that overrode the process-wide ::operator new/::operator
|
||||||
|
// delete, which affected every allocation in the whole unit-regression2
|
||||||
|
// binary rather than just the values under test.
|
||||||
|
std::size_t failing_allocator_allocations = 0;
|
||||||
|
std::size_t failing_allocator_deallocations = 0;
|
||||||
|
bool fail_next_allocation = false;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct failing_allocator : std::allocator<T>
|
||||||
|
{
|
||||||
|
using std::allocator<T>::allocator;
|
||||||
|
|
||||||
|
failing_allocator() noexcept = default;
|
||||||
|
template<class U>
|
||||||
|
failing_allocator(const failing_allocator<U>& /*unused*/) noexcept {} // NOLINT(google-explicit-constructor)
|
||||||
|
|
||||||
|
T* allocate(std::size_t n)
|
||||||
|
{
|
||||||
|
if (fail_next_allocation)
|
||||||
|
{
|
||||||
|
fail_next_allocation = false;
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
++failing_allocator_allocations;
|
||||||
|
return std::allocator<T>::allocate(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
++failing_allocator_deallocations;
|
||||||
|
std::allocator<T>::deallocate(p, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind
|
||||||
|
{
|
||||||
|
using other = failing_allocator<U>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
using failing_json = nlohmann::basic_json<std::map, std::vector, std::string, bool,
|
||||||
|
std::int64_t, std::uint64_t, double, failing_allocator>;
|
||||||
|
using failing_ordered_json = nlohmann::basic_json<nlohmann::ordered_map, std::vector, std::string, bool,
|
||||||
|
std::int64_t, std::uint64_t, double, failing_allocator>;
|
||||||
|
|
||||||
|
// builds `depth` levels of nesting around a scalar, iteratively (never
|
||||||
|
// recursing: each wrap only moves the previous, already-built value, which
|
||||||
|
// is O(1)), each level an array or an object depending on `nest_objects`
|
||||||
|
template<class BasicJsonType>
|
||||||
|
BasicJsonType make_deep_nest(std::size_t depth, bool nest_objects)
|
||||||
|
{
|
||||||
|
BasicJsonType v = 0;
|
||||||
|
for (std::size_t i = 0; i < depth; ++i)
|
||||||
|
{
|
||||||
|
if (nest_objects)
|
||||||
|
{
|
||||||
|
BasicJsonType wrapper = BasicJsonType::object();
|
||||||
|
wrapper["x"] = std::move(v);
|
||||||
|
v = std::move(wrapper);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BasicJsonType wrapper = BasicJsonType::array();
|
||||||
|
wrapper.push_back(std::move(v));
|
||||||
|
v = std::move(wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// for #1647
|
// for #1647
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@@ -569,7 +649,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.begin(), data.end());
|
const json j = json::from_msgpack(data.data(), data.size());
|
||||||
// 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(
|
||||||
@@ -940,4 +1020,211 @@ TEST_CASE("regression test - excessive binary container size honors allow_except
|
|||||||
CHECK(json::from_cbor(std::vector<std::uint8_t> {0x9b, 0, 0, 0, 0, 0, 0, 0, 0x02}, true, false).is_discarded());
|
CHECK(json::from_cbor(std::vector<std::uint8_t> {0x9b, 0, 0, 0, 0, 0, 0, 0, 0x02}, true, false).is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||||
|
TEST_CASE("regression test #5135 - destructor never allocates, even under memory pressure")
|
||||||
|
{
|
||||||
|
// Before the fix, ~basic_json() flattened a nested array/object into a
|
||||||
|
// heap-allocated std::vector to avoid recursing; that allocation could
|
||||||
|
// itself throw bad_alloc, which escapes a noexcept destructor and
|
||||||
|
// terminates the program. destroy() no longer allocates anything, so
|
||||||
|
// none of the sections below ever observe fail_next_allocation being
|
||||||
|
// consumed: CHECK(fail_next_allocation) confirms it was never touched.
|
||||||
|
|
||||||
|
SECTION("the original report: a small, mixed array/object nest")
|
||||||
|
{
|
||||||
|
failing_allocator_allocations = 0;
|
||||||
|
failing_allocator_deallocations = 0;
|
||||||
|
{
|
||||||
|
failing_json j = failing_json::array(
|
||||||
|
{
|
||||||
|
failing_json::array({1, 2}),
|
||||||
|
failing_json::object({{"key", failing_json::array({3})}})
|
||||||
|
});
|
||||||
|
fail_next_allocation = true;
|
||||||
|
} // j is destroyed here, with every further allocation set to fail
|
||||||
|
|
||||||
|
CHECK(fail_next_allocation);
|
||||||
|
fail_next_allocation = false;
|
||||||
|
CHECK(failing_allocator_deallocations > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("100000-deep nested array")
|
||||||
|
{
|
||||||
|
std::size_t allocations_before = 0;
|
||||||
|
{
|
||||||
|
failing_json j = make_deep_nest<failing_json>(100000, false);
|
||||||
|
allocations_before = failing_allocator_allocations;
|
||||||
|
fail_next_allocation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(fail_next_allocation);
|
||||||
|
fail_next_allocation = false;
|
||||||
|
CHECK(failing_allocator_allocations == allocations_before);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("100000-deep nested object")
|
||||||
|
{
|
||||||
|
std::size_t allocations_before = 0;
|
||||||
|
{
|
||||||
|
failing_json j = make_deep_nest<failing_json>(100000, true);
|
||||||
|
allocations_before = failing_allocator_allocations;
|
||||||
|
fail_next_allocation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(fail_next_allocation);
|
||||||
|
fail_next_allocation = false;
|
||||||
|
CHECK(failing_allocator_allocations == allocations_before);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("100000-deep nested ordered_json")
|
||||||
|
{
|
||||||
|
std::size_t allocations_before = 0;
|
||||||
|
{
|
||||||
|
failing_ordered_json j = make_deep_nest<failing_ordered_json>(100000, true);
|
||||||
|
allocations_before = failing_allocator_allocations;
|
||||||
|
fail_next_allocation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(fail_next_allocation);
|
||||||
|
fail_next_allocation = false;
|
||||||
|
CHECK(failing_allocator_allocations == allocations_before);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wide and deep: 1000 arrays of 1000 elements, each a small nested object")
|
||||||
|
{
|
||||||
|
std::size_t allocations_before = 0;
|
||||||
|
{
|
||||||
|
failing_json wide = failing_json::array();
|
||||||
|
for (std::size_t i = 0; i < 1000; ++i)
|
||||||
|
{
|
||||||
|
failing_json inner = failing_json::array();
|
||||||
|
for (std::size_t k = 0; k < 1000; ++k)
|
||||||
|
{
|
||||||
|
inner.push_back(failing_json::object({{"a", 1}, {"b", failing_json::array({1, 2, 3})}}));
|
||||||
|
}
|
||||||
|
wide.push_back(std::move(inner));
|
||||||
|
}
|
||||||
|
|
||||||
|
allocations_before = failing_allocator_allocations;
|
||||||
|
fail_next_allocation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(fail_next_allocation);
|
||||||
|
fail_next_allocation = false;
|
||||||
|
CHECK(failing_allocator_allocations == allocations_before);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// a single-element chain of `depth` arrays, built iteratively (never
|
||||||
|
// recursing: each wrap only moves the previous, already-built value)
|
||||||
|
template<class BasicJsonType>
|
||||||
|
BasicJsonType make_single_chain(std::size_t depth)
|
||||||
|
{
|
||||||
|
BasicJsonType v = 1;
|
||||||
|
for (std::size_t i = 0; i < depth; ++i)
|
||||||
|
{
|
||||||
|
BasicJsonType wrapper = BasicJsonType::array();
|
||||||
|
wrapper.push_back(std::move(v));
|
||||||
|
v = std::move(wrapper);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copies value first, to make sure nothing was corrupted by building it,
|
||||||
|
// then lets both the copy and the original destruct via normal scope exit
|
||||||
|
template<class BasicJsonType>
|
||||||
|
void check_destroy_edge_case(const BasicJsonType& value)
|
||||||
|
{
|
||||||
|
const BasicJsonType copy = value;
|
||||||
|
CHECK(copy == value);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE_TEMPLATE("regression test #5135 - destroy() edge cases", BasicJsonType, json, ordered_json)
|
||||||
|
{
|
||||||
|
using binary_t = typename BasicJsonType::binary_t;
|
||||||
|
|
||||||
|
SECTION("mix of empty objects, empty arrays, non-empty containers, and scalars")
|
||||||
|
{
|
||||||
|
BasicJsonType root = BasicJsonType::array();
|
||||||
|
root.push_back(BasicJsonType::object());
|
||||||
|
root.push_back(BasicJsonType::array());
|
||||||
|
root.push_back(BasicJsonType::object({{"k", 1}}));
|
||||||
|
root.push_back(BasicJsonType::array({1, 2, 3}));
|
||||||
|
root.push_back(nullptr);
|
||||||
|
root.push_back(true);
|
||||||
|
root.push_back(42);
|
||||||
|
root.push_back(3.14);
|
||||||
|
root.push_back("a string");
|
||||||
|
root.push_back(BasicJsonType(binary_t({1, 2, 3})));
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("container child in first position only")
|
||||||
|
{
|
||||||
|
BasicJsonType root = BasicJsonType::array({BasicJsonType::array({1, 2}), 3, 4, 5});
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("container child in last position only")
|
||||||
|
{
|
||||||
|
BasicJsonType root = BasicJsonType::array({1, 2, 3, BasicJsonType::array({4, 5})});
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("container children in first and last position")
|
||||||
|
{
|
||||||
|
BasicJsonType root = BasicJsonType::array({BasicJsonType::array({1}), 2, 3, BasicJsonType::array({4})});
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("single-element chain, 1000 levels deep")
|
||||||
|
{
|
||||||
|
BasicJsonType root = make_single_chain<BasicJsonType>(1000);
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("top-level empty array")
|
||||||
|
{
|
||||||
|
BasicJsonType root = BasicJsonType::array();
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("top-level empty object")
|
||||||
|
{
|
||||||
|
BasicJsonType root = BasicJsonType::object();
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("object whose last child is a non-empty array whose last child is an empty object")
|
||||||
|
{
|
||||||
|
BasicJsonType inner_array = BasicJsonType::array({1, 2, BasicJsonType::object()});
|
||||||
|
BasicJsonType root = BasicJsonType::object({{"a", 1}, {"b", inner_array}});
|
||||||
|
check_destroy_edge_case(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("destruction via erase() on a deeply nested child")
|
||||||
|
{
|
||||||
|
BasicJsonType root = BasicJsonType::array();
|
||||||
|
root.push_back(make_single_chain<BasicJsonType>(500));
|
||||||
|
root.push_back(BasicJsonType::object({{"k", BasicJsonType::array({1, 2, 3})}}));
|
||||||
|
// erase() must destroy the removed subtree without recursing or
|
||||||
|
// allocating beyond what erase() itself needs
|
||||||
|
root.erase(0);
|
||||||
|
CAPTURE(root.size())
|
||||||
|
CHECK(root.size() == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("destruction via assignment on a deep tree")
|
||||||
|
{
|
||||||
|
BasicJsonType root = make_single_chain<BasicJsonType>(2000);
|
||||||
|
// assigning a new value destroys the old one in place
|
||||||
|
root = nullptr;
|
||||||
|
CHECK(root.is_null());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||||
|
|||||||
@@ -8,14 +8,6 @@
|
|||||||
|
|
||||||
#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;
|
||||||
|
|
||||||
@@ -56,7 +48,6 @@ TEST_CASE("serialization")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef JSON_TEST_DEPRECATED_FUNCTIONS_DELETED
|
|
||||||
SECTION("operator>>")
|
SECTION("operator>>")
|
||||||
{
|
{
|
||||||
SECTION("no given width")
|
SECTION("no given width")
|
||||||
@@ -88,7 +79,6 @@ 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,14 +8,6 @@
|
|||||||
|
|
||||||
#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;
|
||||||
|
|
||||||
@@ -2220,10 +2212,8 @@ 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")
|
||||||
@@ -2971,14 +2961,12 @@ 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