mirror of
https://github.com/nlohmann/json.git
synced 2026-09-30 19:50:34 +00:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a7416a922 | ||
|
|
ebfa914346 | ||
|
|
5d4296e455 | ||
|
|
a96d1b3a1e | ||
|
|
adc7217e3b | ||
|
|
b7c8f4ee43 | ||
|
|
7be3deb8d3 | ||
|
|
08032158a3 | ||
|
|
50912bf83f | ||
|
|
f257ac3373 | ||
|
|
6f3b7c05c2 | ||
|
|
0ad9cc3c1d | ||
|
|
b640bf728d | ||
|
|
27db8bd678 | ||
|
|
819838839d | ||
|
|
20bbb137ba | ||
|
|
146b9e7615 |
+10
-5
@@ -1,9 +1,15 @@
|
|||||||
# TODO: The first three checks are only removed to get the CI going. They have to be addressed at some point.
|
# bugprone-use-after-move (hicpp-invalid-access-moved is its alias) still flags
|
||||||
# TODO: portability-avoid-pragma-once: should be fixed eventually
|
# the basic_json move constructor, which forwards the whole object to its base
|
||||||
|
# class (#5724), and two forwards in the error-message construction of
|
||||||
|
# at(KeyType&&) (json.hpp, both overloads: find(std::forward<KeyType>(key))
|
||||||
|
# followed by string_t(std::forward<KeyType>(key)) in the throw), which #5689
|
||||||
|
# rewrites. Re-enable both checks once those changes have landed.
|
||||||
|
# portability-avoid-pragma-once: kept disabled on purpose. #pragma once is accepted
|
||||||
|
# by every supported compiler, and tools/amalgamate/amalgamate.py strips it from
|
||||||
|
# single_include, so there is nothing left to fix here.
|
||||||
|
|
||||||
Checks: '*,
|
Checks: '*,
|
||||||
|
|
||||||
-portability-template-virtual-member-function,
|
|
||||||
-bugprone-use-after-move,
|
-bugprone-use-after-move,
|
||||||
-hicpp-invalid-access-moved,
|
-hicpp-invalid-access-moved,
|
||||||
|
|
||||||
@@ -37,7 +43,6 @@ Checks: '*,
|
|||||||
-google-readability-function-size,
|
-google-readability-function-size,
|
||||||
-google-runtime-float,
|
-google-runtime-float,
|
||||||
-google-runtime-int,
|
-google-runtime-int,
|
||||||
-google-runtime-references,
|
|
||||||
-hicpp-avoid-goto,
|
-hicpp-avoid-goto,
|
||||||
-hicpp-explicit-conversions,
|
-hicpp-explicit-conversions,
|
||||||
-hicpp-function-size,
|
-hicpp-function-size,
|
||||||
@@ -71,6 +76,7 @@ Checks: '*,
|
|||||||
-readability-magic-numbers,
|
-readability-magic-numbers,
|
||||||
-readability-redundant-access-specifiers,
|
-readability-redundant-access-specifiers,
|
||||||
-readability-redundant-parentheses,
|
-readability-redundant-parentheses,
|
||||||
|
-readability-redundant-typename,
|
||||||
-readability-simplify-boolean-expr,
|
-readability-simplify-boolean-expr,
|
||||||
-readability-uppercase-literal-suffix,
|
-readability-uppercase-literal-suffix,
|
||||||
-readability-use-concise-preprocessor-directives'
|
-readability-use-concise-preprocessor-directives'
|
||||||
@@ -81,5 +87,4 @@ CheckOptions:
|
|||||||
|
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
|
|
||||||
#HeaderFilterRegex: '.*nlohmann.*'
|
|
||||||
HeaderFilterRegex: '.*hpp$'
|
HeaderFilterRegex: '.*hpp$'
|
||||||
|
|||||||
@@ -78,13 +78,13 @@ jobs:
|
|||||||
|
|
||||||
ci_static_analysis_clang:
|
ci_static_analysis_clang:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: silkeh/clang:dev
|
container: silkeh/clang:22
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_clang_analyze, ci_single_binaries]
|
target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_single_binaries]
|
||||||
steps:
|
steps:
|
||||||
- name: Install git, clang-tools, iwyu (ci_single_binaries), and unzip
|
- name: Install git, iwyu (ci_single_binaries), and unzip
|
||||||
run: apt-get update ; apt-get install -y git clang-tools iwyu unzip
|
run: apt-get update ; apt-get install -y git iwyu unzip
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|||||||
+4
-20
@@ -8,24 +8,24 @@ set(N 10)
|
|||||||
include(FindPython3)
|
include(FindPython3)
|
||||||
find_package(Python3 COMPONENTS Interpreter)
|
find_package(Python3 COMPONENTS Interpreter)
|
||||||
|
|
||||||
find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-20 clang++-19 clang++-18 clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++)
|
find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-22 clang++-21 clang++-20 clang++-19 clang++-18 clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++)
|
||||||
execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION)
|
execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION)
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}")
|
||||||
message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})")
|
message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})")
|
||||||
|
|
||||||
find_program(CLANG_TIDY_TOOL NAMES clang-tidy-20 clang-tidy-19 clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy)
|
find_program(CLANG_TIDY_TOOL NAMES clang-tidy-22 clang-tidy-21 clang-tidy-20 clang-tidy-19 clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy)
|
||||||
execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION)
|
execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION)
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}")
|
||||||
message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})")
|
message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})")
|
||||||
|
|
||||||
message(STATUS "🔖 CMake ${CMAKE_VERSION} (${CMAKE_COMMAND})")
|
message(STATUS "🔖 CMake ${CMAKE_VERSION} (${CMAKE_COMMAND})")
|
||||||
|
|
||||||
find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++ g++-15 g++-14 g++-13 g++-12 g++-11 g++-10)
|
find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++ g++-16 g++-15 g++-14 g++-13 g++-12 g++-11 g++-10)
|
||||||
execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION)
|
execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION)
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}")
|
||||||
message(STATUS "🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})")
|
message(STATUS "🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})")
|
||||||
|
|
||||||
find_program(GCOV_TOOL NAMES gcov-HEAD gcov gcov-15 gcov-14 gcov-13 gcov-12 gcov-11 gcov-10)
|
find_program(GCOV_TOOL NAMES gcov-HEAD gcov gcov-16 gcov-15 gcov-14 gcov-13 gcov-12 gcov-11 gcov-10)
|
||||||
execute_process(COMMAND ${GCOV_TOOL} --version OUTPUT_VARIABLE GCOV_TOOL_VERSION ERROR_VARIABLE GCOV_TOOL_VERSION)
|
execute_process(COMMAND ${GCOV_TOOL} --version OUTPUT_VARIABLE GCOV_TOOL_VERSION ERROR_VARIABLE GCOV_TOOL_VERSION)
|
||||||
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCOV_TOOL_VERSION "${GCOV_TOOL_VERSION}")
|
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCOV_TOOL_VERSION "${GCOV_TOOL_VERSION}")
|
||||||
message(STATUS "🔖 GCOV ${GCOV_TOOL_VERSION} (${GCOV_TOOL})")
|
message(STATUS "🔖 GCOV ${GCOV_TOOL_VERSION} (${GCOV_TOOL})")
|
||||||
@@ -69,7 +69,6 @@ message(STATUS "🔖 Valgrind ${VALGRIND_TOOL_VERSION} (${VALGRIND_TOOL})")
|
|||||||
find_program(GENHTML_TOOL NAMES genhtml)
|
find_program(GENHTML_TOOL NAMES genhtml)
|
||||||
find_program(PLOG_CONVERTER_TOOL NAMES plog-converter)
|
find_program(PLOG_CONVERTER_TOOL NAMES plog-converter)
|
||||||
find_program(PVS_STUDIO_ANALYZER_TOOL NAMES pvs-studio-analyzer)
|
find_program(PVS_STUDIO_ANALYZER_TOOL NAMES pvs-studio-analyzer)
|
||||||
find_program(SCAN_BUILD_TOOL NAMES scan-build-15 scan-build-14 scan-build-13 scan-build-12 scan-build-11 scan-build)
|
|
||||||
|
|
||||||
# the individual source files
|
# the individual source files
|
||||||
file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp)
|
file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp)
|
||||||
@@ -426,21 +425,6 @@ add_custom_target(ci_test_valgrind
|
|||||||
COMMENT "Compile and test with Valgrind"
|
COMMENT "Compile and test with Valgrind"
|
||||||
)
|
)
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Check code with Clang Static Analyzer.
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
set(CLANG_ANALYZER_CHECKS "fuchsia.HandleChecker,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,optin.cplusplus.UninitializedObject,optin.cplusplus.VirtualCall,optin.mpi.MPI-Checker,optin.osx.OSObjectCStyleCast,optin.osx.cocoa.localizability.EmptyLocalizationContextChecker,optin.osx.cocoa.localizability.NonLocalizedStringChecker,optin.performance.GCDAntipattern,optin.performance.Padding,optin.portability.UnixAPI,security.FloatLoopCounter,security.insecureAPI.DeprecatedOrUnsafeBufferHandling,security.insecureAPI.bcmp,security.insecureAPI.bcopy,security.insecureAPI.bzero,security.insecureAPI.rand,security.insecureAPI.strcpy,valist.CopyToSelf,valist.Uninitialized,valist.Unterminated,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,core.CallAndMessage,core.DivideZero,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.VLASize,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.PlacementNew,cplusplus.PureVirtualCall,deadcode.DeadStores,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,osx.API,osx.MIG,osx.NumberObjectConversion,osx.OSObjectRetainCount,osx.ObjCProperty,osx.SecKeychainAPI,osx.cocoa.AtSync,osx.cocoa.AutoreleaseWrite,osx.cocoa.ClassRelease,osx.cocoa.Dealloc,osx.cocoa.IncompatibleMethodTypes,osx.cocoa.Loops,osx.cocoa.MissingSuperCall,osx.cocoa.NSAutoreleasePool,osx.cocoa.NSError,osx.cocoa.NilArg,osx.cocoa.NonNilReturnValue,osx.cocoa.ObjCGenerics,osx.cocoa.RetainCount,osx.cocoa.RunLoopAutoreleaseLeak,osx.cocoa.SelfInit,osx.cocoa.SuperDealloc,osx.cocoa.UnusedIvars,osx.cocoa.VariadicMethodTypes,osx.coreFoundation.CFError,osx.coreFoundation.CFNumber,osx.coreFoundation.CFRetainRelease,osx.coreFoundation.containers.OutOfBounds,osx.coreFoundation.containers.PointerSizedValues,security.insecureAPI.UncheckedReturn,security.insecureAPI.decodeValueOfObjCType,security.insecureAPI.getpw,security.insecureAPI.gets,security.insecureAPI.mkstemp,security.insecureAPI.mktemp,security.insecureAPI.vfork,unix.API,unix.Malloc,unix.MallocSizeof,unix.MismatchedDeallocator,unix.Vfork,unix.cstring.BadSizeArg,unix.cstring.NullArg")
|
|
||||||
|
|
||||||
add_custom_target(ci_clang_analyze
|
|
||||||
COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND}
|
|
||||||
-DCMAKE_BUILD_TYPE=Debug -GNinja
|
|
||||||
-DJSON_BuildTests=ON
|
|
||||||
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_analyze
|
|
||||||
COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_analyze && ${SCAN_BUILD_TOOL} -enable-checker ${CLANG_ANALYZER_CHECKS} --use-c++=${CLANG_TOOL} -analyze-headers -o ${PROJECT_BINARY_DIR}/report ninja
|
|
||||||
COMMENT "Check code with Clang Analyzer"
|
|
||||||
)
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Check code with Cppcheck.
|
# Check code with Cppcheck.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# -Wno-c++98-compat The library targets C++11.
|
# -Wno-c++98-compat The library targets C++11.
|
||||||
# -Wno-c++98-compat-pedantic The library targets C++11.
|
# -Wno-c++98-compat-pedantic The library targets C++11.
|
||||||
# -Wno-deprecated-declarations The library contains annotations for deprecated functions.
|
# -Wno-deprecated-declarations The library contains annotations for deprecated functions.
|
||||||
# -Wno-extra-semi-stmt The library uses assert which triggers this warning.
|
|
||||||
# -Wno-padded We do not care about padding warnings.
|
# -Wno-padded We do not care about padding warnings.
|
||||||
# -Wno-covered-switch-default All switches list all cases and a default case.
|
# -Wno-covered-switch-default All switches list all cases and a default case.
|
||||||
# -Wno-c2y-extensions Clang 22.1 diagnoses __COUNTER__ as a C2y extension, also in
|
# -Wno-c2y-extensions Clang 22.1 diagnoses __COUNTER__ as a C2y extension, also in
|
||||||
@@ -20,7 +19,6 @@ set(CLANG_CXXFLAGS
|
|||||||
-Wno-c++98-compat
|
-Wno-c++98-compat
|
||||||
-Wno-c++98-compat-pedantic
|
-Wno-c++98-compat-pedantic
|
||||||
-Wno-deprecated-declarations
|
-Wno-deprecated-declarations
|
||||||
-Wno-extra-semi-stmt
|
|
||||||
-Wno-padded
|
-Wno-padded
|
||||||
-Wno-covered-switch-default
|
-Wno-covered-switch-default
|
||||||
-Wno-c2y-extensions
|
-Wno-c2y-extensions
|
||||||
|
|||||||
+24
-13
@@ -1,4 +1,4 @@
|
|||||||
# Warning flags determined for GCC 15.1.0 with https://github.com/nlohmann/gcc_flags:
|
# Warning flags determined for GCC 16.2.0 with https://github.com/nlohmann/gcc_flags:
|
||||||
# Ignored GCC warnings:
|
# Ignored GCC warnings:
|
||||||
# -Wno-abi-tag We do not care about ABI tags.
|
# -Wno-abi-tag We do not care about ABI tags.
|
||||||
# -Wno-aggregate-return The library uses aggregate returns.
|
# -Wno-aggregate-return The library uses aggregate returns.
|
||||||
@@ -16,6 +16,8 @@ set(GCC_CXXFLAGS
|
|||||||
--extra-warnings
|
--extra-warnings
|
||||||
-W
|
-W
|
||||||
-WNSObject-attribute
|
-WNSObject-attribute
|
||||||
|
-Wabbreviated-auto-in-template-arg
|
||||||
|
-Wabi
|
||||||
-Wno-abi-tag
|
-Wno-abi-tag
|
||||||
-Waddress
|
-Waddress
|
||||||
-Waddress-of-packed-member
|
-Waddress-of-packed-member
|
||||||
@@ -64,6 +66,7 @@ set(GCC_CXXFLAGS
|
|||||||
-Wanalyzer-tainted-divisor
|
-Wanalyzer-tainted-divisor
|
||||||
-Wanalyzer-tainted-offset
|
-Wanalyzer-tainted-offset
|
||||||
-Wanalyzer-tainted-size
|
-Wanalyzer-tainted-size
|
||||||
|
-Wanalyzer-throw-of-unexpected-type
|
||||||
-Wanalyzer-too-complex
|
-Wanalyzer-too-complex
|
||||||
-Wanalyzer-undefined-behavior-ptrdiff
|
-Wanalyzer-undefined-behavior-ptrdiff
|
||||||
-Wanalyzer-undefined-behavior-strtok
|
-Wanalyzer-undefined-behavior-strtok
|
||||||
@@ -80,10 +83,13 @@ set(GCC_CXXFLAGS
|
|||||||
-Warith-conversion
|
-Warith-conversion
|
||||||
-Warray-bounds=2
|
-Warray-bounds=2
|
||||||
-Warray-compare
|
-Warray-compare
|
||||||
|
-Warray-parameter
|
||||||
-Warray-parameter=2
|
-Warray-parameter=2
|
||||||
-Wattribute-alias=2
|
-Wattribute-alias=2
|
||||||
-Wattribute-warning
|
-Wattribute-warning
|
||||||
-Wattributes
|
-Wattributes
|
||||||
|
-Wauto-profile
|
||||||
|
-Wbidi-chars=any
|
||||||
-Wbool-compare
|
-Wbool-compare
|
||||||
-Wbool-operation
|
-Wbool-operation
|
||||||
-Wbuiltin-declaration-mismatch
|
-Wbuiltin-declaration-mismatch
|
||||||
@@ -99,6 +105,7 @@ set(GCC_CXXFLAGS
|
|||||||
-Wc++20-compat
|
-Wc++20-compat
|
||||||
-Wc++20-extensions
|
-Wc++20-extensions
|
||||||
-Wc++23-extensions
|
-Wc++23-extensions
|
||||||
|
-Wc++26-compat
|
||||||
-Wc++26-extensions
|
-Wc++26-extensions
|
||||||
-Wc++2a-compat
|
-Wc++2a-compat
|
||||||
-Wcalloc-transposed-args
|
-Wcalloc-transposed-args
|
||||||
@@ -142,6 +149,7 @@ set(GCC_CXXFLAGS
|
|||||||
-Wdeprecated-enum-enum-conversion
|
-Wdeprecated-enum-enum-conversion
|
||||||
-Wdeprecated-enum-float-conversion
|
-Wdeprecated-enum-float-conversion
|
||||||
-Wdeprecated-literal-operator
|
-Wdeprecated-literal-operator
|
||||||
|
-Wdeprecated-openmp
|
||||||
-Wdeprecated-variadic-comma-omission
|
-Wdeprecated-variadic-comma-omission
|
||||||
-Wdisabled-optimization
|
-Wdisabled-optimization
|
||||||
-Wdiv-by-zero
|
-Wdiv-by-zero
|
||||||
@@ -156,21 +164,18 @@ set(GCC_CXXFLAGS
|
|||||||
-Wenum-conversion
|
-Wenum-conversion
|
||||||
-Wexceptions
|
-Wexceptions
|
||||||
-Wexpansion-to-defined
|
-Wexpansion-to-defined
|
||||||
|
-Wexperimental-fmv-target
|
||||||
|
-Wexpose-global-module-tu-local
|
||||||
|
-Wexternal-tu-local
|
||||||
-Wextra
|
-Wextra
|
||||||
-Wextra-semi
|
-Wextra-semi
|
||||||
-Wflex-array-member-not-at-end
|
-Wflex-array-member-not-at-end
|
||||||
-Wfloat-conversion
|
-Wfloat-conversion
|
||||||
-Wfloat-equal
|
-Wfloat-equal
|
||||||
-Wformat -Wformat-contains-nul
|
-Wformat-diag
|
||||||
-Wformat -Wformat-diag
|
-Wformat-overflow=2
|
||||||
-Wformat -Wformat-extra-args
|
-Wformat-signedness
|
||||||
-Wformat -Wformat-nonliteral
|
-Wformat-truncation=2
|
||||||
-Wformat -Wformat-overflow=2
|
|
||||||
-Wformat -Wformat-security
|
|
||||||
-Wformat -Wformat-signedness
|
|
||||||
-Wformat -Wformat-truncation=2
|
|
||||||
-Wformat -Wformat-y2k
|
|
||||||
-Wformat -Wformat-zero-length
|
|
||||||
-Wformat=2
|
-Wformat=2
|
||||||
-Wframe-address
|
-Wframe-address
|
||||||
-Wfree-nonheap-object
|
-Wfree-nonheap-object
|
||||||
@@ -197,6 +202,8 @@ set(GCC_CXXFLAGS
|
|||||||
-Winvalid-offsetof
|
-Winvalid-offsetof
|
||||||
-Winvalid-pch
|
-Winvalid-pch
|
||||||
-Winvalid-utf8
|
-Winvalid-utf8
|
||||||
|
-Wkeyword-macro
|
||||||
|
-Wleading-whitespace=spaces
|
||||||
-Wliteral-suffix
|
-Wliteral-suffix
|
||||||
-Wlogical-not-parentheses
|
-Wlogical-not-parentheses
|
||||||
-Wlogical-op
|
-Wlogical-op
|
||||||
@@ -227,6 +234,7 @@ set(GCC_CXXFLAGS
|
|||||||
-Wnarrowing
|
-Wnarrowing
|
||||||
-Wnoexcept
|
-Wnoexcept
|
||||||
-Wnoexcept-type
|
-Wnoexcept-type
|
||||||
|
-Wnon-c-typedef-for-linkage
|
||||||
-Wnon-template-friend
|
-Wnon-template-friend
|
||||||
-Wnon-virtual-dtor
|
-Wnon-virtual-dtor
|
||||||
-Wnonnull
|
-Wnonnull
|
||||||
@@ -269,6 +277,8 @@ set(GCC_CXXFLAGS
|
|||||||
-Wscalar-storage-order
|
-Wscalar-storage-order
|
||||||
-Wself-move
|
-Wself-move
|
||||||
-Wsequence-point
|
-Wsequence-point
|
||||||
|
-Wsfinae-incomplete
|
||||||
|
-Wsfinae-incomplete=2
|
||||||
-Wshadow=compatible-local
|
-Wshadow=compatible-local
|
||||||
-Wshadow=global
|
-Wshadow=global
|
||||||
-Wshadow=local
|
-Wshadow=local
|
||||||
@@ -289,6 +299,7 @@ set(GCC_CXXFLAGS
|
|||||||
-Wstrict-aliasing=3
|
-Wstrict-aliasing=3
|
||||||
-Wstrict-null-sentinel
|
-Wstrict-null-sentinel
|
||||||
-Wstrict-overflow
|
-Wstrict-overflow
|
||||||
|
-Wstrict-overflow=5
|
||||||
-Wstring-compare
|
-Wstring-compare
|
||||||
-Wstringop-overflow
|
-Wstringop-overflow
|
||||||
-Wstringop-overflow=4
|
-Wstringop-overflow=4
|
||||||
@@ -333,8 +344,8 @@ set(GCC_CXXFLAGS
|
|||||||
-Wunreachable-code
|
-Wunreachable-code
|
||||||
-Wunsafe-loop-optimizations
|
-Wunsafe-loop-optimizations
|
||||||
-Wunused
|
-Wunused
|
||||||
-Wunused-but-set-parameter
|
-Wunused-but-set-parameter=3
|
||||||
-Wunused-but-set-variable
|
-Wunused-but-set-variable=3
|
||||||
-Wunused-const-variable=2
|
-Wunused-const-variable=2
|
||||||
-Wunused-function
|
-Wunused-function
|
||||||
-Wunused-label
|
-Wunused-label
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ measures that counter them. The measures are described in detail in [Quality ass
|
|||||||
|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
|
||||||
| Out-of-bounds read/write ([CWE-125](https://cwe.mitre.org/data/definitions/125.html), [CWE-787](https://cwe.mitre.org/data/definitions/787.html)) | bounds checks on all reads from the input; AddressSanitizer and Valgrind on the test suite; OSS-Fuzz |
|
| Out-of-bounds read/write ([CWE-125](https://cwe.mitre.org/data/definitions/125.html), [CWE-787](https://cwe.mitre.org/data/definitions/787.html)) | bounds checks on all reads from the input; AddressSanitizer and Valgrind on the test suite; OSS-Fuzz |
|
||||||
| Integer overflow ([CWE-190](https://cwe.mitre.org/data/definitions/190.html)) | UndefinedBehaviorSanitizer with integer overflow detection; Clang-Tidy; Cppcheck |
|
| Integer overflow ([CWE-190](https://cwe.mitre.org/data/definitions/190.html)) | UndefinedBehaviorSanitizer with integer overflow detection; Clang-Tidy; Cppcheck |
|
||||||
| Use after free, double free ([CWE-416](https://cwe.mitre.org/data/definitions/416.html), [CWE-415](https://cwe.mitre.org/data/definitions/415.html)) | ownership of all memory by values; AddressSanitizer and Valgrind; Clang Static Analyzer |
|
| Use after free, double free ([CWE-416](https://cwe.mitre.org/data/definitions/416.html), [CWE-415](https://cwe.mitre.org/data/definitions/415.html)) | ownership of all memory by values; AddressSanitizer and Valgrind; Clang-Tidy (incl. Clang Static Analyzer checks) |
|
||||||
| Memory leaks ([CWE-401](https://cwe.mitre.org/data/definitions/401.html)) | Valgrind (Memcheck) on the test suite |
|
| Memory leaks ([CWE-401](https://cwe.mitre.org/data/definitions/401.html)) | Valgrind (Memcheck) on the test suite |
|
||||||
| Uncontrolled recursion ([CWE-674](https://cwe.mitre.org/data/definitions/674.html)) | iterative parser, binary readers, and destructor; bounded recursion in value operations; tests with deeply nested inputs |
|
| Uncontrolled recursion ([CWE-674](https://cwe.mitre.org/data/definitions/674.html)) | iterative parser, binary readers, and destructor; bounded recursion in value operations; tests with deeply nested inputs |
|
||||||
| Uncontrolled resource consumption ([CWE-400](https://cwe.mitre.org/data/definitions/400.html)) | allocations based on announced sizes are capped; OSS-Fuzz with memory limits |
|
| Uncontrolled resource consumption ([CWE-400](https://cwe.mitre.org/data/definitions/400.html)) | allocations based on announced sizes are capped; OSS-Fuzz with memory limits |
|
||||||
| Undefined behavior in general ([CWE-758](https://cwe.mitre.org/data/definitions/758.html)) | UndefinedBehaviorSanitizer; runtime assertions; Clang-Tidy, Cppcheck, Clang Static Analyzer, Infer |
|
| Undefined behavior in general ([CWE-758](https://cwe.mitre.org/data/definitions/758.html)) | UndefinedBehaviorSanitizer; runtime assertions; Clang-Tidy (incl. Clang Static Analyzer checks), Cppcheck, Infer |
|
||||||
|
|
||||||
In addition, every line of the library is covered by the unit tests, and all parsers are fuzz-tested around the clock
|
In addition, every line of the library is covered by the unit tests, and all parsers are fuzz-tested around the clock
|
||||||
by [OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json).
|
by [OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json).
|
||||||
|
|||||||
@@ -183,8 +183,8 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
|
|||||||
```
|
```
|
||||||
|
|
||||||
- [x] The code is checked with the latest [Cppcheck](https://cppcheck.sourceforge.io) with all warnings enabled.
|
- [x] The code is checked with the latest [Cppcheck](https://cppcheck.sourceforge.io) with all warnings enabled.
|
||||||
- [x] The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) with 89 enabled
|
- [x] The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) checks, run
|
||||||
rules.
|
through Clang-Tidy's `clang-analyzer-*` checks with warnings as errors.
|
||||||
- [x] The code is checked with [Infer](https://fbinfer.com).
|
- [x] The code is checked with [Infer](https://fbinfer.com).
|
||||||
- [x] The code is checked with [Codacy](https://app.codacy.com/gh/nlohmann/json/dashboard).
|
- [x] The code is checked with [Codacy](https://app.codacy.com/gh/nlohmann/json/dashboard).
|
||||||
|
|
||||||
|
|||||||
@@ -354,22 +354,22 @@ void())
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename T, std::size_t... Idx >
|
template < typename BasicJsonType, typename T, std::size_t... Idx >
|
||||||
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
|
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(const BasicJsonType& j,
|
||||||
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
|
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
|
||||||
{
|
{
|
||||||
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
|
return { { j.at(Idx).template get<T>()... } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename T, std::size_t N >
|
template < typename BasicJsonType, typename T, std::size_t N >
|
||||||
auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
|
auto from_json(const BasicJsonType& j, identity_tag<std::array<T, N>> tag)
|
||||||
-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
|
-> decltype(from_json_inplace_array_impl(j, tag, make_index_sequence<N> {}))
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||||
}
|
}
|
||||||
|
|
||||||
return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
|
return from_json_inplace_array_impl(j, tag, make_index_sequence<N> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
@@ -504,54 +504,54 @@ template<std::size_t PTagValue, typename BasicJsonType, typename... Types>
|
|||||||
using tuple_type = std::tuple < decltype(from_json_tuple_get_impl(std::declval<BasicJsonType>(), detail::identity_tag<Types> {}, detail::priority_tag<PTagValue> {}))... >;
|
using tuple_type = std::tuple < decltype(from_json_tuple_get_impl(std::declval<BasicJsonType>(), detail::identity_tag<Types> {}, detail::priority_tag<PTagValue> {}))... >;
|
||||||
|
|
||||||
template<std::size_t PTagValue, typename... Args, typename BasicJsonType, std::size_t... Idx>
|
template<std::size_t PTagValue, typename... Args, typename BasicJsonType, std::size_t... Idx>
|
||||||
tuple_type<PTagValue, BasicJsonType, Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
|
tuple_type<PTagValue, const BasicJsonType&, Args...> from_json_tuple_impl_base(const BasicJsonType& j, index_sequence<Idx...> /*unused*/)
|
||||||
{
|
{
|
||||||
return tuple_type<PTagValue, BasicJsonType, Args...>(from_json_tuple_get_impl(std::forward<BasicJsonType>(j).at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
|
return tuple_type<PTagValue, const BasicJsonType&, Args...>(from_json_tuple_get_impl(j.at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t PTagValue, typename BasicJsonType>
|
template<std::size_t PTagValue, typename BasicJsonType>
|
||||||
std::tuple<> from_json_tuple_impl_base(BasicJsonType& /*unused*/, index_sequence<> /*unused*/)
|
std::tuple<> from_json_tuple_impl_base(const BasicJsonType& /*unused*/, index_sequence<> /*unused*/)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, class A1, class A2 >
|
template < typename BasicJsonType, class A1, class A2 >
|
||||||
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
|
std::pair<A1, A2> from_json_tuple_impl(const BasicJsonType& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
|
||||||
{
|
{
|
||||||
return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
|
return {j.at(0).template get<A1>(),
|
||||||
std::forward<BasicJsonType>(j).at(1).template get<A2>()};
|
j.at(1).template get<A2>()};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename A1, typename A2>
|
template<typename BasicJsonType, typename A1, typename A2>
|
||||||
inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
|
inline void from_json_tuple_impl(const BasicJsonType& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
|
||||||
{
|
{
|
||||||
p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
|
p = from_json_tuple_impl(j, identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
|
std::tuple<Args...> from_json_tuple_impl(const BasicJsonType& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
|
||||||
{
|
{
|
||||||
static_assert(cxpr_and<cxpr_or<cxpr_not<std::is_reference<Args>>, is_compatible_reference_type<BasicJsonType, Args>>...>::value,
|
static_assert(cxpr_and<cxpr_or<cxpr_not<std::is_reference<Args>>, is_compatible_reference_type<const BasicJsonType&, Args>>...>::value,
|
||||||
"Can not return a tuple containing references to types not contained in a Json, try Json::get_to()");
|
"Can not return a tuple containing references to types not contained in a Json, try Json::get_to()");
|
||||||
return from_json_tuple_impl_base<1, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
|
return from_json_tuple_impl_base<1, Args...>(j, index_sequence_for<Args...> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
|
inline void from_json_tuple_impl(const BasicJsonType& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
|
||||||
{
|
{
|
||||||
t = from_json_tuple_impl_base<2, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
|
t = from_json_tuple_impl_base<2, Args...>(j, index_sequence_for<Args...> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename TupleRelated>
|
template<typename BasicJsonType, typename TupleRelated>
|
||||||
auto from_json(BasicJsonType&& j, TupleRelated&& t)
|
auto from_json(const BasicJsonType& j, TupleRelated&& t)
|
||||||
-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
|
-> decltype(from_json_tuple_impl(j, std::forward<TupleRelated>(t), priority_tag<3> {}))
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||||
}
|
}
|
||||||
|
|
||||||
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
|
return from_json_tuple_impl(j, std::forward<TupleRelated>(t), priority_tag<3> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
||||||
@@ -636,7 +636,7 @@ struct from_json_fn
|
|||||||
/// namespace to hold default `from_json` function
|
/// namespace to hold default `from_json` function
|
||||||
/// to see why this is required:
|
/// to see why this is required:
|
||||||
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
||||||
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
|
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces,misc-anonymous-namespace-in-header)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
|
JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
|
||||||
|
|||||||
@@ -546,7 +546,7 @@ struct to_json_fn
|
|||||||
/// namespace to hold default `to_json` function
|
/// namespace to hold default `to_json` function
|
||||||
/// to see why this is required:
|
/// to see why this is required:
|
||||||
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
||||||
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
|
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces,misc-anonymous-namespace-in-header)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
|
JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ class binary_reader
|
|||||||
@brief Parses a C-style string from the BSON input.
|
@brief Parses a C-style string from the BSON input.
|
||||||
@param[in,out] result A reference to the string variable where the read
|
@param[in,out] result A reference to the string variable where the read
|
||||||
string is to be stored.
|
string is to be stored.
|
||||||
@return `true` if the \x00-byte indicating the end of the string was
|
@return `true` if the \\x00-byte indicating the end of the string was
|
||||||
encountered before the EOF; false` indicates an unexpected EOF.
|
encountered before the EOF; false` indicates an unexpected EOF.
|
||||||
*/
|
*/
|
||||||
bool get_bson_cstr(string_t& result)
|
bool get_bson_cstr(string_t& result)
|
||||||
@@ -437,7 +437,7 @@ class binary_reader
|
|||||||
@brief read a C-style string from contiguous input in one step
|
@brief read a C-style string from contiguous input in one step
|
||||||
|
|
||||||
@param[in,out] result the string to append to
|
@param[in,out] result the string to append to
|
||||||
@return whether the string was read; if the input has no \x00-byte, nothing
|
@return whether the string was read; if the input has no \\x00-byte, nothing
|
||||||
is read, and @ref get_bson_cstr reports the end of the input
|
is read, and @ref get_bson_cstr reports the end of the input
|
||||||
*/
|
*/
|
||||||
bool get_bson_cstr_bulk(string_t& result, std::true_type /*bulk*/)
|
bool get_bson_cstr_bulk(string_t& result, std::true_type /*bulk*/)
|
||||||
|
|||||||
@@ -769,6 +769,9 @@ struct container_input_adapter_factory< ContainerType,
|
|||||||
|
|
||||||
static adapter_type create(ContainerType&& container)
|
static adapter_type create(ContainerType&& container)
|
||||||
{
|
{
|
||||||
|
// container is forwarded twice on purpose: the resulting begin/end
|
||||||
|
// iterator types must match adapter_type, computed the same way
|
||||||
|
// NOLINTNEXTLINE(bugprone-use-after-move)
|
||||||
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
|
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ class json_sax_dom_parser
|
|||||||
}
|
}
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
// Handle all possible types discretely, default handler should never be reached.
|
// Handle all possible types discretely, default handler should never be reached.
|
||||||
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
|
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,7 +903,7 @@ class json_sax_dom_callback_parser
|
|||||||
}
|
}
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
// Handle all possible types discretely, default handler should never be reached.
|
// Handle all possible types discretely, default handler should never be reached.
|
||||||
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
|
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,9 +220,9 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
/////////////////////
|
/////////////////////
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief get codepoint from 4 hex characters following `\u`
|
@brief get codepoint from 4 hex characters following `\\u`
|
||||||
|
|
||||||
For input "\u c1 c2 c3 c4" the codepoint is:
|
For input "\\u c1 c2 c3 c4" the codepoint is:
|
||||||
(c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
|
(c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
|
||||||
= (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
|
= (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ This class implements a both iterators (iterator and const_iterator) for the
|
|||||||
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
||||||
default-constructed, it is *uninitialized* and most methods are undefined.
|
default-constructed, it is *uninitialized* and most methods are undefined.
|
||||||
**The library uses assertions to detect calls on uninitialized iterators.**
|
**The library uses assertions to detect calls on uninitialized iterators.**
|
||||||
@requirement REQ-JSON-01 The class satisfies the following concept requirements:
|
This class satisfies the following concept requirements (REQ-JSON-01):
|
||||||
-
|
-
|
||||||
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
||||||
The iterator that can be moved can be moved in both directions (i.e.
|
The iterator that can be moved can be moved in both directions (i.e.
|
||||||
|
|||||||
@@ -213,11 +213,11 @@ namespace std
|
|||||||
JSON_HEDLEY_PRAGMA(clang diagnostic ignored "-Wmismatched-tags")
|
JSON_HEDLEY_PRAGMA(clang diagnostic ignored "-Wmismatched-tags")
|
||||||
#endif
|
#endif
|
||||||
template<typename IteratorType>
|
template<typename IteratorType>
|
||||||
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
|
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
: public std::integral_constant<std::size_t, 2> {};
|
: public std::integral_constant<std::size_t, 2> {};
|
||||||
|
|
||||||
template<std::size_t N, typename IteratorType>
|
template<std::size_t N, typename IteratorType>
|
||||||
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
|
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using type = decltype(
|
using type = decltype(
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace detail
|
|||||||
iterator (to create @ref reverse_iterator) and @ref const_iterator (to
|
iterator (to create @ref reverse_iterator) and @ref const_iterator (to
|
||||||
create @ref const_reverse_iterator).
|
create @ref const_reverse_iterator).
|
||||||
|
|
||||||
@requirement REQ-JSON-02 The class satisfies the following concept requirements:
|
This class satisfies the following concept requirements (REQ-JSON-02):
|
||||||
-
|
-
|
||||||
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
||||||
The iterator that can be moved can be moved in both directions (i.e.
|
The iterator that can be moved can be moved in both directions (i.e.
|
||||||
|
|||||||
@@ -278,11 +278,11 @@ class json_pointer
|
|||||||
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
|
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// only triggered on special platforms (like 32bit), see also
|
// the index does not fit into size_type; on 64-bit platforms this is
|
||||||
// https://github.com/nlohmann/json/pull/2203
|
// only SIZE_MAX itself (see #2203 and #5395)
|
||||||
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
|
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
|
||||||
{
|
{
|
||||||
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
|
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<size_type>(res);
|
return static_cast<size_type>(res);
|
||||||
@@ -316,7 +316,7 @@ class json_pointer
|
|||||||
/*!
|
/*!
|
||||||
@brief create and return a reference to the pointed to value
|
@brief create and return a reference to the pointed to value
|
||||||
|
|
||||||
@complexity Linear in the number of reference tokens.
|
Complexity: Linear in the number of reference tokens.
|
||||||
|
|
||||||
@throw parse_error.106 if an array index begins with '0'
|
@throw parse_error.106 if an array index begins with '0'
|
||||||
@throw parse_error.109 if array index is not a number
|
@throw parse_error.109 if array index is not a number
|
||||||
@@ -403,7 +403,7 @@ class json_pointer
|
|||||||
|
|
||||||
@return reference to the JSON value pointed to by the JSON pointer
|
@return reference to the JSON value pointed to by the JSON pointer
|
||||||
|
|
||||||
@complexity Linear in the length of the JSON pointer.
|
Complexity: Linear in the length of the JSON pointer.
|
||||||
|
|
||||||
@throw parse_error.106 if an array index begins with '0'
|
@throw parse_error.106 if an array index begins with '0'
|
||||||
@throw parse_error.109 if an array index was not a number
|
@throw parse_error.109 if an array index was not a number
|
||||||
|
|||||||
@@ -195,13 +195,6 @@
|
|||||||
#define JSON_NO_THREAD_LOCAL 1
|
#define JSON_NO_THREAD_LOCAL 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// disable documentation warnings on clang
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
||||||
#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// allow disabling exceptions
|
// allow disabling exceptions
|
||||||
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||||
#define JSON_THROW(exception) throw exception
|
#define JSON_THROW(exception) throw exception
|
||||||
@@ -260,7 +253,7 @@
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
@@ -274,7 +267,7 @@
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
@@ -313,7 +306,7 @@ void templated_json_throw(ExceptionType exception)
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
@@ -328,7 +321,7 @@ void templated_json_throw(ExceptionType exception)
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
|
|||||||
@@ -8,11 +8,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// restore clang diagnostic settings
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
#undef JSON_ASSERT
|
#undef JSON_ASSERT
|
||||||
#undef JSON_INTERNAL_CATCH
|
#undef JSON_INTERNAL_CATCH
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <iterator> // back_inserter
|
#include <iterator> // back_inserter
|
||||||
#include <memory> // shared_ptr, make_shared
|
#include <memory> // shared_ptr, make_shared
|
||||||
#include <string> // basic_string
|
#include <string> // basic_string
|
||||||
|
#include <type_traits> // conditional, integral_constant, is_same
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
@@ -117,12 +118,14 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
|
|||||||
: stream(s)
|
: stream(s)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(portability-template-virtual-member-function)
|
||||||
void write_character(CharType c) override
|
void write_character(CharType c) override
|
||||||
{
|
{
|
||||||
stream.put(c);
|
stream.put(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
|
// NOLINTNEXTLINE(portability-template-virtual-member-function)
|
||||||
void write_characters(const CharType* s, std::size_t length) override
|
void write_characters(const CharType* s, std::size_t length) override
|
||||||
{
|
{
|
||||||
stream.write(s, static_cast<std::streamsize>(length));
|
stream.write(s, static_cast<std::streamsize>(length));
|
||||||
@@ -190,7 +193,82 @@ class output_adapter_sink
|
|||||||
output_adapter_t<CharType> oa;
|
output_adapter_t<CharType> oa;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename CharType, typename StringType = std::basic_string<CharType>>
|
/// @brief whether std::basic_string<CharType> has a non-deprecated std::char_traits
|
||||||
|
/// specialization, and is therefore usable as output_adapter's default StringType
|
||||||
|
///
|
||||||
|
/// std::char_traits is only guaranteed (and, on some standard libraries, only
|
||||||
|
/// implemented without a deprecation warning) for the character types listed
|
||||||
|
/// below; std::char_traits<T> for any other T (e.g. std::uint8_t, as used by the
|
||||||
|
/// binary writers) is a non-standard extension some standard libraries deprecate.
|
||||||
|
/// See https://github.com/nlohmann/json/issues/5725 item 2.
|
||||||
|
template<typename CharType>
|
||||||
|
struct is_output_adapter_string_char_type : std::integral_constant < bool,
|
||||||
|
std::is_same<CharType, char>::value ||
|
||||||
|
std::is_same<CharType, wchar_t>::value ||
|
||||||
|
std::is_same<CharType, char16_t>::value ||
|
||||||
|
std::is_same<CharType, char32_t>::value
|
||||||
|
#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
|
||||||
|
|| std::is_same<CharType, char8_t>::value
|
||||||
|
#endif
|
||||||
|
> {};
|
||||||
|
|
||||||
|
/// @brief placeholder type for output_adapter's StringType and (with JSON_NO_IO
|
||||||
|
/// undefined) its std::basic_ostream constructor parameter, for CharType
|
||||||
|
/// with no non-deprecated std::char_traits specialization
|
||||||
|
///
|
||||||
|
/// Never actually used: the StringType- and std::basic_ostream-based
|
||||||
|
/// output_adapter constructors are neither documented nor tested for such
|
||||||
|
/// CharType (only the std::vector-based constructor is used for them, by the
|
||||||
|
/// binary writers). Naming std::basic_string<CharType> or
|
||||||
|
/// std::basic_ostream<CharType> anywhere such a constructor would otherwise be
|
||||||
|
/// declared - even as an unused default template argument or an unused,
|
||||||
|
/// never-called overload - instantiates std::char_traits<CharType> merely to
|
||||||
|
/// name the type, which is exactly what triggers the deprecation warning this
|
||||||
|
/// placeholder avoids.
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_no_string_type {};
|
||||||
|
|
||||||
|
// Select output_adapter's default StringType (and, below, its ostream
|
||||||
|
// constructor's parameter type) via partial specialization, not
|
||||||
|
// std::conditional: std::conditional<B, T, F> requires both T and F to be named
|
||||||
|
// as template arguments up front, which would still instantiate (and thus name)
|
||||||
|
// std::basic_string<CharType> / std::basic_ostream<CharType> for every CharType,
|
||||||
|
// defeating the point. A bool non-type parameter with two specializations only
|
||||||
|
// ever names the type that is actually selected.
|
||||||
|
template<typename CharType, bool = is_output_adapter_string_char_type<CharType>::value>
|
||||||
|
struct output_adapter_default_string_type
|
||||||
|
{
|
||||||
|
using type = output_adapter_no_string_type<CharType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_default_string_type<CharType, true>
|
||||||
|
{
|
||||||
|
using type = std::basic_string<CharType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef JSON_NO_IO
|
||||||
|
/// distinct from output_adapter_no_string_type, so the placeholder overloads of
|
||||||
|
/// output_adapter's constructor (used when CharType is not a character type)
|
||||||
|
/// stay distinct overloads instead of colliding into a single redeclaration
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_no_ostream_type {};
|
||||||
|
|
||||||
|
template<typename CharType, bool = is_output_adapter_string_char_type<CharType>::value>
|
||||||
|
struct output_adapter_ostream_type
|
||||||
|
{
|
||||||
|
using type = output_adapter_no_ostream_type<CharType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_ostream_type<CharType, true>
|
||||||
|
{
|
||||||
|
using type = std::basic_ostream<CharType>;
|
||||||
|
};
|
||||||
|
#endif // JSON_NO_IO
|
||||||
|
|
||||||
|
template < typename CharType, typename StringType =
|
||||||
|
typename output_adapter_default_string_type<CharType>::type >
|
||||||
class output_adapter
|
class output_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -199,7 +277,7 @@ class output_adapter
|
|||||||
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
|
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
|
||||||
|
|
||||||
#ifndef JSON_NO_IO
|
#ifndef JSON_NO_IO
|
||||||
output_adapter(std::basic_ostream<CharType>& s)
|
output_adapter(typename output_adapter_ostream_type<CharType>::type& s)
|
||||||
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
||||||
#endif // JSON_NO_IO
|
#endif // JSON_NO_IO
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class serializer
|
|||||||
@param[in] ichar indentation character to use
|
@param[in] ichar indentation character to use
|
||||||
@param[in] pretty_print_ whether the output shall be pretty-printed
|
@param[in] pretty_print_ whether the output shall be pretty-printed
|
||||||
@param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII
|
@param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII
|
||||||
characters in the output are escaped with `\uXXXX` sequences, and the
|
characters in the output are escaped with `\\uXXXX` sequences, and the
|
||||||
result consists of ASCII characters only.
|
result consists of ASCII characters only.
|
||||||
@param[in] indent_step_ the indent level
|
@param[in] indent_step_ the indent level
|
||||||
@param[in] error_handler_ how to react on decoding errors
|
@param[in] error_handler_ how to react on decoding errors
|
||||||
@@ -772,7 +772,7 @@ class serializer
|
|||||||
|
|
||||||
@param[in] s the string to escape
|
@param[in] s the string to escape
|
||||||
|
|
||||||
@complexity Linear in the length of string @a s.
|
Complexity: Linear in the length of string @a s.
|
||||||
*/
|
*/
|
||||||
void dump_escaped(const string_t& s)
|
void dump_escaped(const string_t& s)
|
||||||
{
|
{
|
||||||
@@ -1290,7 +1290,7 @@ class serializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief write a lowercase "\uXXXX" escape sequence into @a string_buffer
|
* @brief write a lowercase "\\uXXXX" escape sequence into @a string_buffer
|
||||||
*
|
*
|
||||||
* Branch-free replacement for `snprintf(buf, 7, "\\u%04x", codeunit)` in the
|
* Branch-free replacement for `snprintf(buf, 7, "\\u%04x", codeunit)` in the
|
||||||
* string escaping hot path. It writes exactly six characters ('\\', 'u' and
|
* string escaping hot path. It writes exactly six characters ('\\', 'u' and
|
||||||
@@ -1650,7 +1650,7 @@ class serializer
|
|||||||
/// whether to pretty-print the output
|
/// whether to pretty-print the output
|
||||||
const bool pretty_print;
|
const bool pretty_print;
|
||||||
|
|
||||||
/// whether to escape non-ASCII characters with \uXXXX sequences
|
/// whether to escape non-ASCII characters with \\uXXXX sequences
|
||||||
const bool ensure_ascii;
|
const bool ensure_ascii;
|
||||||
|
|
||||||
/// the indent level
|
/// the indent level
|
||||||
|
|||||||
@@ -62,8 +62,7 @@ inline StringType escape(const StringType& s)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief string unescaping as described in RFC 6901 (Sect. 4)
|
* @brief string unescaping as described in RFC 6901 (Sect. 4)
|
||||||
* @param[in] s string to unescape
|
* @param[in,out] s string to unescape in place
|
||||||
* @return unescaped string
|
|
||||||
*
|
*
|
||||||
* Note the order of escaping "~1" to "/" and "~0" to "~" is important.
|
* Note the order of escaping "~1" to "/" and "~0" to "~" is important.
|
||||||
*
|
*
|
||||||
|
|||||||
+36
-35
@@ -18,16 +18,6 @@
|
|||||||
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
|
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
|
||||||
#define INCLUDE_NLOHMANN_JSON_HPP_
|
#define INCLUDE_NLOHMANN_JSON_HPP_
|
||||||
|
|
||||||
// Workaround for GCC template redefinition errors in C++ modules
|
|
||||||
// When nlohmann/json.hpp is included in a C++20 module preamble after
|
|
||||||
// other module imports, GCC may report spurious redefinition errors for
|
|
||||||
// STL templates. These pragmas suppress those false positives.
|
|
||||||
// See: https://github.com/nlohmann/json/issues/5103
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <algorithm> // all_of, find, for_each, none_of
|
#include <algorithm> // all_of, find, for_each, none_of
|
||||||
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
||||||
#include <functional> // hash, less
|
#include <functional> // hash, less
|
||||||
@@ -2350,12 +2340,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@throw what @ref json_serializer<ValueType> `from_json()` method throws
|
@throw what @ref json_serializer<ValueType> `from_json()` method throws
|
||||||
|
|
||||||
@liveexample{The example below shows several conversions from JSON values
|
The example below shows several conversions from JSON values
|
||||||
to other types. There a few things to note: (1) Floating-point numbers can
|
to other types. There a few things to note: (1) Floating-point numbers can
|
||||||
be converted to integers\, (2) A JSON array can be converted to a standard
|
be converted to integers, (2) A JSON array can be converted to a standard
|
||||||
`std::vector<short>`\, (3) A JSON object can be converted to C++
|
`std::vector<short>`, (3) A JSON object can be converted to C++
|
||||||
associative containers such as `std::unordered_map<std::string\,
|
associative containers such as `std::unordered_map<std::string,
|
||||||
json>`.,get__ValueType_const}
|
json>`.
|
||||||
|
|
||||||
@since version 2.1.0
|
@since version 2.1.0
|
||||||
*/
|
*/
|
||||||
@@ -2422,7 +2412,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@return a copy of *this, converted into @a BasicJsonType
|
@return a copy of *this, converted into @a BasicJsonType
|
||||||
|
|
||||||
@complexity Depending on the implementation of the called `from_json()`
|
Complexity: Depending on the implementation of the called `from_json()`
|
||||||
method.
|
method.
|
||||||
|
|
||||||
@since version 3.2.0
|
@since version 3.2.0
|
||||||
@@ -2446,7 +2436,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@return a copy of *this
|
@return a copy of *this
|
||||||
|
|
||||||
@complexity Constant.
|
Complexity: Constant.
|
||||||
|
|
||||||
@since version 2.1.0
|
@since version 2.1.0
|
||||||
*/
|
*/
|
||||||
@@ -2492,7 +2482,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
@tparam ValueTypeCV the provided value type
|
@tparam ValueTypeCV the provided value type
|
||||||
@tparam ValueType the returned value type
|
@tparam ValueType the returned value type
|
||||||
|
|
||||||
@return copy of the JSON value, converted to @tparam ValueType if necessary
|
@return copy of the JSON value, converted to @a ValueType if necessary
|
||||||
|
|
||||||
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
|
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
|
||||||
|
|
||||||
@@ -2530,12 +2520,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
@return pointer to the internally stored JSON value if the requested
|
@return pointer to the internally stored JSON value if the requested
|
||||||
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
|
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
|
||||||
|
|
||||||
@complexity Constant.
|
Complexity: Constant.
|
||||||
|
|
||||||
@liveexample{The example below shows how pointers to internal values of a
|
The example below shows how pointers to internal values of a
|
||||||
JSON value can be requested. Note that no type conversions are made and a
|
JSON value can be requested. Note that no type conversions are made and a
|
||||||
`nullptr` is returned if the value and the requested pointer type does not
|
`nullptr` is returned if the value and the requested pointer type does not
|
||||||
match.,get__PointerType}
|
match.
|
||||||
|
|
||||||
@sa see @ref get_ptr() for explicit pointer-member access
|
@sa see @ref get_ptr() for explicit pointer-member access
|
||||||
|
|
||||||
@@ -2629,14 +2619,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
to the JSON value type (e.g., the JSON value is of type boolean, but a
|
to the JSON value type (e.g., the JSON value is of type boolean, but a
|
||||||
string is requested); see example below
|
string is requested); see example below
|
||||||
|
|
||||||
@complexity Linear in the size of the JSON value.
|
Complexity: Linear in the size of the JSON value.
|
||||||
|
|
||||||
@liveexample{The example below shows several conversions from JSON values
|
The example below shows several conversions from JSON values
|
||||||
to other types. There a few things to note: (1) Floating-point numbers can
|
to other types. There a few things to note: (1) Floating-point numbers can
|
||||||
be converted to integers\, (2) A JSON array can be converted to a standard
|
be converted to integers, (2) A JSON array can be converted to a standard
|
||||||
`std::vector<short>`\, (3) A JSON object can be converted to C++
|
`std::vector<short>`, (3) A JSON object can be converted to C++
|
||||||
associative containers such as `std::unordered_map<std::string\,
|
associative containers such as `std::unordered_map<std::string,
|
||||||
json>`.,operator__ValueType}
|
json>`.
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
@@ -5059,6 +5049,19 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @deprecated This function is deprecated since 3.8.0 and will be removed in
|
/// @deprecated This function is deprecated since 3.8.0 and will be removed in
|
||||||
/// version 4.0.0 of the library. Please use
|
/// version 4.0.0 of the library. Please use
|
||||||
/// sax_parse(ptr, ptr + len) instead.
|
/// sax_parse(ptr, ptr + len) instead.
|
||||||
|
//
|
||||||
|
// Clang reports "declaration is marked with '@deprecated' command but does
|
||||||
|
// not have a deprecation attribute" for this overload even though
|
||||||
|
// JSON_HEDLEY_DEPRECATED_FOR below does expand to __attribute__((deprecated));
|
||||||
|
// isolated reproductions of this exact declaration shape (doc comment,
|
||||||
|
// template<>, two stacked __attribute__ lines, an overload set of the same
|
||||||
|
// name) do not reproduce it, so this looks like a Clang comment/declaration
|
||||||
|
// association quirk specific to this overload within basic_json, not a
|
||||||
|
// genuine documentation bug. See #5725 item 2.
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdocumentation-deprecated-sync"
|
||||||
|
#endif
|
||||||
template <typename SAX>
|
template <typename SAX>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
@@ -5075,6 +5078,9 @@ 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(format, sax, strict);
|
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
|
||||||
}
|
}
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
#ifndef JSON_NO_IO
|
#ifndef JSON_NO_IO
|
||||||
/// @brief deserialize from stream
|
/// @brief deserialize from stream
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
|
||||||
@@ -6495,7 +6501,7 @@ namespace std // NOLINT(cert-dcl58-cpp)
|
|||||||
/// @brief hash value for JSON objects
|
/// @brief hash value for JSON objects
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/std_hash/
|
/// @sa https://json.nlohmann.me/api/basic_json/std_hash/
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
|
struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
{
|
{
|
||||||
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
|
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
|
||||||
{
|
{
|
||||||
@@ -6528,7 +6534,7 @@ struct less< ::nlohmann::detail::value_t> // do not remove the space after '<',
|
|||||||
/// @brief exchanges the values of two JSON objects
|
/// @brief exchanges the values of two JSON objects
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/std_swap/
|
/// @sa https://json.nlohmann.me/api/basic_json/std_swap/
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)
|
inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
||||||
is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
|
is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
|
||||||
{
|
{
|
||||||
@@ -6542,7 +6548,7 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC
|
|||||||
/// @brief std::formatter specialization for JSON values
|
/// @brief std::formatter specialization for JSON values
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/std_formatter/
|
/// @sa https://json.nlohmann.me/api/basic_json/std_formatter/
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-cpp)
|
struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
{
|
{
|
||||||
// -1 means compact output (dump()); any value >= 0 means pretty-printed
|
// -1 means compact output (dump()); any value >= 0 means pretty-printed
|
||||||
// output with that many spaces (or indent_char) per level (dump(indent, indent_char)).
|
// output with that many spaces (or indent_char) per level (dump(indent, indent_char)).
|
||||||
@@ -6619,11 +6625,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
|
|||||||
|
|
||||||
#include <nlohmann/detail/macro_unscope.hpp>
|
#include <nlohmann/detail/macro_unscope.hpp>
|
||||||
|
|
||||||
// End of GCC diagnostic pragmas for C++ modules support
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The user-defined string literals are in a separate header, because their
|
// The user-defined string literals are in a separate header, because their
|
||||||
// bodies instantiate the parser in every translation unit that includes them.
|
// bodies instantiate the parser in every translation unit that includes them.
|
||||||
// Define JSON_NO_AUTOMATIC_UDLS to include <nlohmann/json_literals.hpp> only
|
// Define JSON_NO_AUTOMATIC_UDLS to include <nlohmann/json_literals.hpp> only
|
||||||
|
|||||||
@@ -18,16 +18,6 @@
|
|||||||
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
|
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
|
||||||
#define INCLUDE_NLOHMANN_JSON_HPP_
|
#define INCLUDE_NLOHMANN_JSON_HPP_
|
||||||
|
|
||||||
// Workaround for GCC template redefinition errors in C++ modules
|
|
||||||
// When nlohmann/json.hpp is included in a C++20 module preamble after
|
|
||||||
// other module imports, GCC may report spurious redefinition errors for
|
|
||||||
// STL templates. These pragmas suppress those false positives.
|
|
||||||
// See: https://github.com/nlohmann/json/issues/5103
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <algorithm> // all_of, find, for_each, none_of
|
#include <algorithm> // all_of, find, for_each, none_of
|
||||||
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
||||||
#include <functional> // hash, less
|
#include <functional> // hash, less
|
||||||
@@ -2608,13 +2598,6 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
#define JSON_NO_THREAD_LOCAL 1
|
#define JSON_NO_THREAD_LOCAL 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// disable documentation warnings on clang
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
||||||
#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// allow disabling exceptions
|
// allow disabling exceptions
|
||||||
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||||
#define JSON_THROW(exception) throw exception
|
#define JSON_THROW(exception) throw exception
|
||||||
@@ -2673,7 +2656,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
@@ -2687,7 +2670,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
@@ -2726,7 +2709,7 @@ void templated_json_throw(ExceptionType exception)
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
@@ -2741,7 +2724,7 @@ void templated_json_throw(ExceptionType exception)
|
|||||||
{ \
|
{ \
|
||||||
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
/* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
|
||||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||||
/* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
/* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on <array> */ \
|
||||||
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
|
||||||
auto it = std::find_if(std::begin(m), std::end(m), \
|
auto it = std::find_if(std::begin(m), std::end(m), \
|
||||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||||
@@ -3560,8 +3543,7 @@ inline StringType escape(const StringType& s)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief string unescaping as described in RFC 6901 (Sect. 4)
|
* @brief string unescaping as described in RFC 6901 (Sect. 4)
|
||||||
* @param[in] s string to unescape
|
* @param[in,out] s string to unescape in place
|
||||||
* @return unescaped string
|
|
||||||
*
|
*
|
||||||
* Note the order of escaping "~1" to "/" and "~0" to "~" is important.
|
* Note the order of escaping "~1" to "/" and "~0" to "~" is important.
|
||||||
*
|
*
|
||||||
@@ -5849,22 +5831,22 @@ void())
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename T, std::size_t... Idx >
|
template < typename BasicJsonType, typename T, std::size_t... Idx >
|
||||||
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
|
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(const BasicJsonType& j,
|
||||||
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
|
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
|
||||||
{
|
{
|
||||||
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
|
return { { j.at(Idx).template get<T>()... } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename T, std::size_t N >
|
template < typename BasicJsonType, typename T, std::size_t N >
|
||||||
auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
|
auto from_json(const BasicJsonType& j, identity_tag<std::array<T, N>> tag)
|
||||||
-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
|
-> decltype(from_json_inplace_array_impl(j, tag, make_index_sequence<N> {}))
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||||
}
|
}
|
||||||
|
|
||||||
return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
|
return from_json_inplace_array_impl(j, tag, make_index_sequence<N> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
@@ -5999,54 +5981,54 @@ template<std::size_t PTagValue, typename BasicJsonType, typename... Types>
|
|||||||
using tuple_type = std::tuple < decltype(from_json_tuple_get_impl(std::declval<BasicJsonType>(), detail::identity_tag<Types> {}, detail::priority_tag<PTagValue> {}))... >;
|
using tuple_type = std::tuple < decltype(from_json_tuple_get_impl(std::declval<BasicJsonType>(), detail::identity_tag<Types> {}, detail::priority_tag<PTagValue> {}))... >;
|
||||||
|
|
||||||
template<std::size_t PTagValue, typename... Args, typename BasicJsonType, std::size_t... Idx>
|
template<std::size_t PTagValue, typename... Args, typename BasicJsonType, std::size_t... Idx>
|
||||||
tuple_type<PTagValue, BasicJsonType, Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
|
tuple_type<PTagValue, const BasicJsonType&, Args...> from_json_tuple_impl_base(const BasicJsonType& j, index_sequence<Idx...> /*unused*/)
|
||||||
{
|
{
|
||||||
return tuple_type<PTagValue, BasicJsonType, Args...>(from_json_tuple_get_impl(std::forward<BasicJsonType>(j).at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
|
return tuple_type<PTagValue, const BasicJsonType&, Args...>(from_json_tuple_get_impl(j.at(Idx), detail::identity_tag<Args> {}, detail::priority_tag<PTagValue> {})...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t PTagValue, typename BasicJsonType>
|
template<std::size_t PTagValue, typename BasicJsonType>
|
||||||
std::tuple<> from_json_tuple_impl_base(BasicJsonType& /*unused*/, index_sequence<> /*unused*/)
|
std::tuple<> from_json_tuple_impl_base(const BasicJsonType& /*unused*/, index_sequence<> /*unused*/)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, class A1, class A2 >
|
template < typename BasicJsonType, class A1, class A2 >
|
||||||
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
|
std::pair<A1, A2> from_json_tuple_impl(const BasicJsonType& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
|
||||||
{
|
{
|
||||||
return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
|
return {j.at(0).template get<A1>(),
|
||||||
std::forward<BasicJsonType>(j).at(1).template get<A2>()};
|
j.at(1).template get<A2>()};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename A1, typename A2>
|
template<typename BasicJsonType, typename A1, typename A2>
|
||||||
inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
|
inline void from_json_tuple_impl(const BasicJsonType& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
|
||||||
{
|
{
|
||||||
p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
|
p = from_json_tuple_impl(j, identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
|
std::tuple<Args...> from_json_tuple_impl(const BasicJsonType& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
|
||||||
{
|
{
|
||||||
static_assert(cxpr_and<cxpr_or<cxpr_not<std::is_reference<Args>>, is_compatible_reference_type<BasicJsonType, Args>>...>::value,
|
static_assert(cxpr_and<cxpr_or<cxpr_not<std::is_reference<Args>>, is_compatible_reference_type<const BasicJsonType&, Args>>...>::value,
|
||||||
"Can not return a tuple containing references to types not contained in a Json, try Json::get_to()");
|
"Can not return a tuple containing references to types not contained in a Json, try Json::get_to()");
|
||||||
return from_json_tuple_impl_base<1, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
|
return from_json_tuple_impl_base<1, Args...>(j, index_sequence_for<Args...> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename... Args>
|
template<typename BasicJsonType, typename... Args>
|
||||||
inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
|
inline void from_json_tuple_impl(const BasicJsonType& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
|
||||||
{
|
{
|
||||||
t = from_json_tuple_impl_base<2, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
|
t = from_json_tuple_impl_base<2, Args...>(j, index_sequence_for<Args...> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename TupleRelated>
|
template<typename BasicJsonType, typename TupleRelated>
|
||||||
auto from_json(BasicJsonType&& j, TupleRelated&& t)
|
auto from_json(const BasicJsonType& j, TupleRelated&& t)
|
||||||
-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
|
-> decltype(from_json_tuple_impl(j, std::forward<TupleRelated>(t), priority_tag<3> {}))
|
||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||||
{
|
{
|
||||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||||
}
|
}
|
||||||
|
|
||||||
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
|
return from_json_tuple_impl(j, std::forward<TupleRelated>(t), priority_tag<3> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
||||||
@@ -6131,7 +6113,7 @@ struct from_json_fn
|
|||||||
/// namespace to hold default `from_json` function
|
/// namespace to hold default `from_json` function
|
||||||
/// to see why this is required:
|
/// to see why this is required:
|
||||||
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
||||||
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
|
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces,misc-anonymous-namespace-in-header)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
|
JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
|
||||||
@@ -6529,11 +6511,11 @@ namespace std
|
|||||||
JSON_HEDLEY_PRAGMA(clang diagnostic ignored "-Wmismatched-tags")
|
JSON_HEDLEY_PRAGMA(clang diagnostic ignored "-Wmismatched-tags")
|
||||||
#endif
|
#endif
|
||||||
template<typename IteratorType>
|
template<typename IteratorType>
|
||||||
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
|
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
: public std::integral_constant<std::size_t, 2> {};
|
: public std::integral_constant<std::size_t, 2> {};
|
||||||
|
|
||||||
template<std::size_t N, typename IteratorType>
|
template<std::size_t N, typename IteratorType>
|
||||||
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
|
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using type = decltype(
|
using type = decltype(
|
||||||
@@ -7077,7 +7059,7 @@ struct to_json_fn
|
|||||||
/// namespace to hold default `to_json` function
|
/// namespace to hold default `to_json` function
|
||||||
/// to see why this is required:
|
/// to see why this is required:
|
||||||
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
|
||||||
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
|
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces,misc-anonymous-namespace-in-header)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
|
JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
|
||||||
@@ -8321,6 +8303,9 @@ struct container_input_adapter_factory< ContainerType,
|
|||||||
|
|
||||||
static adapter_type create(ContainerType&& container)
|
static adapter_type create(ContainerType&& container)
|
||||||
{
|
{
|
||||||
|
// container is forwarded twice on purpose: the resulting begin/end
|
||||||
|
// iterator types must match adapter_type, computed the same way
|
||||||
|
// NOLINTNEXTLINE(bugprone-use-after-move)
|
||||||
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
|
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -10216,9 +10201,9 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
/////////////////////
|
/////////////////////
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief get codepoint from 4 hex characters following `\u`
|
@brief get codepoint from 4 hex characters following `\\u`
|
||||||
|
|
||||||
For input "\u c1 c2 c3 c4" the codepoint is:
|
For input "\\u c1 c2 c3 c4" the codepoint is:
|
||||||
(c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
|
(c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
|
||||||
= (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
|
= (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
|
||||||
|
|
||||||
@@ -12611,7 +12596,7 @@ class json_sax_dom_parser
|
|||||||
}
|
}
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
// Handle all possible types discretely, default handler should never be reached.
|
// Handle all possible types discretely, default handler should never be reached.
|
||||||
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
|
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13074,7 +13059,7 @@ class json_sax_dom_callback_parser
|
|||||||
}
|
}
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
// Handle all possible types discretely, default handler should never be reached.
|
// Handle all possible types discretely, default handler should never be reached.
|
||||||
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
|
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13943,7 +13928,7 @@ class binary_reader
|
|||||||
@brief Parses a C-style string from the BSON input.
|
@brief Parses a C-style string from the BSON input.
|
||||||
@param[in,out] result A reference to the string variable where the read
|
@param[in,out] result A reference to the string variable where the read
|
||||||
string is to be stored.
|
string is to be stored.
|
||||||
@return `true` if the \x00-byte indicating the end of the string was
|
@return `true` if the \\x00-byte indicating the end of the string was
|
||||||
encountered before the EOF; false` indicates an unexpected EOF.
|
encountered before the EOF; false` indicates an unexpected EOF.
|
||||||
*/
|
*/
|
||||||
bool get_bson_cstr(string_t& result)
|
bool get_bson_cstr(string_t& result)
|
||||||
@@ -13973,7 +13958,7 @@ class binary_reader
|
|||||||
@brief read a C-style string from contiguous input in one step
|
@brief read a C-style string from contiguous input in one step
|
||||||
|
|
||||||
@param[in,out] result the string to append to
|
@param[in,out] result the string to append to
|
||||||
@return whether the string was read; if the input has no \x00-byte, nothing
|
@return whether the string was read; if the input has no \\x00-byte, nothing
|
||||||
is read, and @ref get_bson_cstr reports the end of the input
|
is read, and @ref get_bson_cstr reports the end of the input
|
||||||
*/
|
*/
|
||||||
bool get_bson_cstr_bulk(string_t& result, std::true_type /*bulk*/)
|
bool get_bson_cstr_bulk(string_t& result, std::true_type /*bulk*/)
|
||||||
@@ -18683,7 +18668,7 @@ This class implements a both iterators (iterator and const_iterator) for the
|
|||||||
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
been set (e.g., by a constructor or a copy assignment). If the iterator is
|
||||||
default-constructed, it is *uninitialized* and most methods are undefined.
|
default-constructed, it is *uninitialized* and most methods are undefined.
|
||||||
**The library uses assertions to detect calls on uninitialized iterators.**
|
**The library uses assertions to detect calls on uninitialized iterators.**
|
||||||
@requirement REQ-JSON-01 The class satisfies the following concept requirements:
|
This class satisfies the following concept requirements (REQ-JSON-01):
|
||||||
-
|
-
|
||||||
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
||||||
The iterator that can be moved can be moved in both directions (i.e.
|
The iterator that can be moved can be moved in both directions (i.e.
|
||||||
@@ -19447,7 +19432,7 @@ namespace detail
|
|||||||
iterator (to create @ref reverse_iterator) and @ref const_iterator (to
|
iterator (to create @ref reverse_iterator) and @ref const_iterator (to
|
||||||
create @ref const_reverse_iterator).
|
create @ref const_reverse_iterator).
|
||||||
|
|
||||||
@requirement REQ-JSON-02 The class satisfies the following concept requirements:
|
This class satisfies the following concept requirements (REQ-JSON-02):
|
||||||
-
|
-
|
||||||
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
|
||||||
The iterator that can be moved can be moved in both directions (i.e.
|
The iterator that can be moved can be moved in both directions (i.e.
|
||||||
@@ -19890,11 +19875,11 @@ class json_pointer
|
|||||||
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
|
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// only triggered on special platforms (like 32bit), see also
|
// the index does not fit into size_type; on 64-bit platforms this is
|
||||||
// https://github.com/nlohmann/json/pull/2203
|
// only SIZE_MAX itself (see #2203 and #5395)
|
||||||
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
|
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
|
||||||
{
|
{
|
||||||
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
|
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<size_type>(res);
|
return static_cast<size_type>(res);
|
||||||
@@ -19928,7 +19913,7 @@ class json_pointer
|
|||||||
/*!
|
/*!
|
||||||
@brief create and return a reference to the pointed to value
|
@brief create and return a reference to the pointed to value
|
||||||
|
|
||||||
@complexity Linear in the number of reference tokens.
|
Complexity: Linear in the number of reference tokens.
|
||||||
|
|
||||||
@throw parse_error.106 if an array index begins with '0'
|
@throw parse_error.106 if an array index begins with '0'
|
||||||
@throw parse_error.109 if array index is not a number
|
@throw parse_error.109 if array index is not a number
|
||||||
@@ -20015,7 +20000,7 @@ class json_pointer
|
|||||||
|
|
||||||
@return reference to the JSON value pointed to by the JSON pointer
|
@return reference to the JSON value pointed to by the JSON pointer
|
||||||
|
|
||||||
@complexity Linear in the length of the JSON pointer.
|
Complexity: Linear in the length of the JSON pointer.
|
||||||
|
|
||||||
@throw parse_error.106 if an array index begins with '0'
|
@throw parse_error.106 if an array index begins with '0'
|
||||||
@throw parse_error.109 if an array index was not a number
|
@throw parse_error.109 if an array index was not a number
|
||||||
@@ -20928,6 +20913,7 @@ NLOHMANN_JSON_NAMESPACE_END
|
|||||||
#include <iterator> // back_inserter
|
#include <iterator> // back_inserter
|
||||||
#include <memory> // shared_ptr, make_shared
|
#include <memory> // shared_ptr, make_shared
|
||||||
#include <string> // basic_string
|
#include <string> // basic_string
|
||||||
|
#include <type_traits> // conditional, integral_constant, is_same
|
||||||
#include <utility> // move
|
#include <utility> // move
|
||||||
#include <vector> // vector
|
#include <vector> // vector
|
||||||
|
|
||||||
@@ -21033,12 +21019,14 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
|
|||||||
: stream(s)
|
: stream(s)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(portability-template-virtual-member-function)
|
||||||
void write_character(CharType c) override
|
void write_character(CharType c) override
|
||||||
{
|
{
|
||||||
stream.put(c);
|
stream.put(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
|
// NOLINTNEXTLINE(portability-template-virtual-member-function)
|
||||||
void write_characters(const CharType* s, std::size_t length) override
|
void write_characters(const CharType* s, std::size_t length) override
|
||||||
{
|
{
|
||||||
stream.write(s, static_cast<std::streamsize>(length));
|
stream.write(s, static_cast<std::streamsize>(length));
|
||||||
@@ -21106,7 +21094,82 @@ class output_adapter_sink
|
|||||||
output_adapter_t<CharType> oa;
|
output_adapter_t<CharType> oa;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename CharType, typename StringType = std::basic_string<CharType>>
|
/// @brief whether std::basic_string<CharType> has a non-deprecated std::char_traits
|
||||||
|
/// specialization, and is therefore usable as output_adapter's default StringType
|
||||||
|
///
|
||||||
|
/// std::char_traits is only guaranteed (and, on some standard libraries, only
|
||||||
|
/// implemented without a deprecation warning) for the character types listed
|
||||||
|
/// below; std::char_traits<T> for any other T (e.g. std::uint8_t, as used by the
|
||||||
|
/// binary writers) is a non-standard extension some standard libraries deprecate.
|
||||||
|
/// See https://github.com/nlohmann/json/issues/5725 item 2.
|
||||||
|
template<typename CharType>
|
||||||
|
struct is_output_adapter_string_char_type : std::integral_constant < bool,
|
||||||
|
std::is_same<CharType, char>::value ||
|
||||||
|
std::is_same<CharType, wchar_t>::value ||
|
||||||
|
std::is_same<CharType, char16_t>::value ||
|
||||||
|
std::is_same<CharType, char32_t>::value
|
||||||
|
#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
|
||||||
|
|| std::is_same<CharType, char8_t>::value
|
||||||
|
#endif
|
||||||
|
> {};
|
||||||
|
|
||||||
|
/// @brief placeholder type for output_adapter's StringType and (with JSON_NO_IO
|
||||||
|
/// undefined) its std::basic_ostream constructor parameter, for CharType
|
||||||
|
/// with no non-deprecated std::char_traits specialization
|
||||||
|
///
|
||||||
|
/// Never actually used: the StringType- and std::basic_ostream-based
|
||||||
|
/// output_adapter constructors are neither documented nor tested for such
|
||||||
|
/// CharType (only the std::vector-based constructor is used for them, by the
|
||||||
|
/// binary writers). Naming std::basic_string<CharType> or
|
||||||
|
/// std::basic_ostream<CharType> anywhere such a constructor would otherwise be
|
||||||
|
/// declared - even as an unused default template argument or an unused,
|
||||||
|
/// never-called overload - instantiates std::char_traits<CharType> merely to
|
||||||
|
/// name the type, which is exactly what triggers the deprecation warning this
|
||||||
|
/// placeholder avoids.
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_no_string_type {};
|
||||||
|
|
||||||
|
// Select output_adapter's default StringType (and, below, its ostream
|
||||||
|
// constructor's parameter type) via partial specialization, not
|
||||||
|
// std::conditional: std::conditional<B, T, F> requires both T and F to be named
|
||||||
|
// as template arguments up front, which would still instantiate (and thus name)
|
||||||
|
// std::basic_string<CharType> / std::basic_ostream<CharType> for every CharType,
|
||||||
|
// defeating the point. A bool non-type parameter with two specializations only
|
||||||
|
// ever names the type that is actually selected.
|
||||||
|
template<typename CharType, bool = is_output_adapter_string_char_type<CharType>::value>
|
||||||
|
struct output_adapter_default_string_type
|
||||||
|
{
|
||||||
|
using type = output_adapter_no_string_type<CharType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_default_string_type<CharType, true>
|
||||||
|
{
|
||||||
|
using type = std::basic_string<CharType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef JSON_NO_IO
|
||||||
|
/// distinct from output_adapter_no_string_type, so the placeholder overloads of
|
||||||
|
/// output_adapter's constructor (used when CharType is not a character type)
|
||||||
|
/// stay distinct overloads instead of colliding into a single redeclaration
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_no_ostream_type {};
|
||||||
|
|
||||||
|
template<typename CharType, bool = is_output_adapter_string_char_type<CharType>::value>
|
||||||
|
struct output_adapter_ostream_type
|
||||||
|
{
|
||||||
|
using type = output_adapter_no_ostream_type<CharType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
struct output_adapter_ostream_type<CharType, true>
|
||||||
|
{
|
||||||
|
using type = std::basic_ostream<CharType>;
|
||||||
|
};
|
||||||
|
#endif // JSON_NO_IO
|
||||||
|
|
||||||
|
template < typename CharType, typename StringType =
|
||||||
|
typename output_adapter_default_string_type<CharType>::type >
|
||||||
class output_adapter
|
class output_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -21115,7 +21178,7 @@ class output_adapter
|
|||||||
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
|
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
|
||||||
|
|
||||||
#ifndef JSON_NO_IO
|
#ifndef JSON_NO_IO
|
||||||
output_adapter(std::basic_ostream<CharType>& s)
|
output_adapter(typename output_adapter_ostream_type<CharType>::type& s)
|
||||||
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
||||||
#endif // JSON_NO_IO
|
#endif // JSON_NO_IO
|
||||||
|
|
||||||
@@ -24936,7 +24999,7 @@ class serializer
|
|||||||
@param[in] ichar indentation character to use
|
@param[in] ichar indentation character to use
|
||||||
@param[in] pretty_print_ whether the output shall be pretty-printed
|
@param[in] pretty_print_ whether the output shall be pretty-printed
|
||||||
@param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII
|
@param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII
|
||||||
characters in the output are escaped with `\uXXXX` sequences, and the
|
characters in the output are escaped with `\\uXXXX` sequences, and the
|
||||||
result consists of ASCII characters only.
|
result consists of ASCII characters only.
|
||||||
@param[in] indent_step_ the indent level
|
@param[in] indent_step_ the indent level
|
||||||
@param[in] error_handler_ how to react on decoding errors
|
@param[in] error_handler_ how to react on decoding errors
|
||||||
@@ -25641,7 +25704,7 @@ class serializer
|
|||||||
|
|
||||||
@param[in] s the string to escape
|
@param[in] s the string to escape
|
||||||
|
|
||||||
@complexity Linear in the length of string @a s.
|
Complexity: Linear in the length of string @a s.
|
||||||
*/
|
*/
|
||||||
void dump_escaped(const string_t& s)
|
void dump_escaped(const string_t& s)
|
||||||
{
|
{
|
||||||
@@ -26159,7 +26222,7 @@ class serializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief write a lowercase "\uXXXX" escape sequence into @a string_buffer
|
* @brief write a lowercase "\\uXXXX" escape sequence into @a string_buffer
|
||||||
*
|
*
|
||||||
* Branch-free replacement for `snprintf(buf, 7, "\\u%04x", codeunit)` in the
|
* Branch-free replacement for `snprintf(buf, 7, "\\u%04x", codeunit)` in the
|
||||||
* string escaping hot path. It writes exactly six characters ('\\', 'u' and
|
* string escaping hot path. It writes exactly six characters ('\\', 'u' and
|
||||||
@@ -26519,7 +26582,7 @@ class serializer
|
|||||||
/// whether to pretty-print the output
|
/// whether to pretty-print the output
|
||||||
const bool pretty_print;
|
const bool pretty_print;
|
||||||
|
|
||||||
/// whether to escape non-ASCII characters with \uXXXX sequences
|
/// whether to escape non-ASCII characters with \\uXXXX sequences
|
||||||
const bool ensure_ascii;
|
const bool ensure_ascii;
|
||||||
|
|
||||||
/// the indent level
|
/// the indent level
|
||||||
@@ -29277,12 +29340,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@throw what @ref json_serializer<ValueType> `from_json()` method throws
|
@throw what @ref json_serializer<ValueType> `from_json()` method throws
|
||||||
|
|
||||||
@liveexample{The example below shows several conversions from JSON values
|
The example below shows several conversions from JSON values
|
||||||
to other types. There a few things to note: (1) Floating-point numbers can
|
to other types. There a few things to note: (1) Floating-point numbers can
|
||||||
be converted to integers\, (2) A JSON array can be converted to a standard
|
be converted to integers, (2) A JSON array can be converted to a standard
|
||||||
`std::vector<short>`\, (3) A JSON object can be converted to C++
|
`std::vector<short>`, (3) A JSON object can be converted to C++
|
||||||
associative containers such as `std::unordered_map<std::string\,
|
associative containers such as `std::unordered_map<std::string,
|
||||||
json>`.,get__ValueType_const}
|
json>`.
|
||||||
|
|
||||||
@since version 2.1.0
|
@since version 2.1.0
|
||||||
*/
|
*/
|
||||||
@@ -29349,7 +29412,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@return a copy of *this, converted into @a BasicJsonType
|
@return a copy of *this, converted into @a BasicJsonType
|
||||||
|
|
||||||
@complexity Depending on the implementation of the called `from_json()`
|
Complexity: Depending on the implementation of the called `from_json()`
|
||||||
method.
|
method.
|
||||||
|
|
||||||
@since version 3.2.0
|
@since version 3.2.0
|
||||||
@@ -29373,7 +29436,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@return a copy of *this
|
@return a copy of *this
|
||||||
|
|
||||||
@complexity Constant.
|
Complexity: Constant.
|
||||||
|
|
||||||
@since version 2.1.0
|
@since version 2.1.0
|
||||||
*/
|
*/
|
||||||
@@ -29419,7 +29482,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
@tparam ValueTypeCV the provided value type
|
@tparam ValueTypeCV the provided value type
|
||||||
@tparam ValueType the returned value type
|
@tparam ValueType the returned value type
|
||||||
|
|
||||||
@return copy of the JSON value, converted to @tparam ValueType if necessary
|
@return copy of the JSON value, converted to @a ValueType if necessary
|
||||||
|
|
||||||
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
|
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
|
||||||
|
|
||||||
@@ -29457,12 +29520,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
@return pointer to the internally stored JSON value if the requested
|
@return pointer to the internally stored JSON value if the requested
|
||||||
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
|
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
|
||||||
|
|
||||||
@complexity Constant.
|
Complexity: Constant.
|
||||||
|
|
||||||
@liveexample{The example below shows how pointers to internal values of a
|
The example below shows how pointers to internal values of a
|
||||||
JSON value can be requested. Note that no type conversions are made and a
|
JSON value can be requested. Note that no type conversions are made and a
|
||||||
`nullptr` is returned if the value and the requested pointer type does not
|
`nullptr` is returned if the value and the requested pointer type does not
|
||||||
match.,get__PointerType}
|
match.
|
||||||
|
|
||||||
@sa see @ref get_ptr() for explicit pointer-member access
|
@sa see @ref get_ptr() for explicit pointer-member access
|
||||||
|
|
||||||
@@ -29556,14 +29619,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
to the JSON value type (e.g., the JSON value is of type boolean, but a
|
to the JSON value type (e.g., the JSON value is of type boolean, but a
|
||||||
string is requested); see example below
|
string is requested); see example below
|
||||||
|
|
||||||
@complexity Linear in the size of the JSON value.
|
Complexity: Linear in the size of the JSON value.
|
||||||
|
|
||||||
@liveexample{The example below shows several conversions from JSON values
|
The example below shows several conversions from JSON values
|
||||||
to other types. There a few things to note: (1) Floating-point numbers can
|
to other types. There a few things to note: (1) Floating-point numbers can
|
||||||
be converted to integers\, (2) A JSON array can be converted to a standard
|
be converted to integers, (2) A JSON array can be converted to a standard
|
||||||
`std::vector<short>`\, (3) A JSON object can be converted to C++
|
`std::vector<short>`, (3) A JSON object can be converted to C++
|
||||||
associative containers such as `std::unordered_map<std::string\,
|
associative containers such as `std::unordered_map<std::string,
|
||||||
json>`.,operator__ValueType}
|
json>`.
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
@@ -31986,6 +32049,19 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/// @deprecated This function is deprecated since 3.8.0 and will be removed in
|
/// @deprecated This function is deprecated since 3.8.0 and will be removed in
|
||||||
/// version 4.0.0 of the library. Please use
|
/// version 4.0.0 of the library. Please use
|
||||||
/// sax_parse(ptr, ptr + len) instead.
|
/// sax_parse(ptr, ptr + len) instead.
|
||||||
|
//
|
||||||
|
// Clang reports "declaration is marked with '@deprecated' command but does
|
||||||
|
// not have a deprecation attribute" for this overload even though
|
||||||
|
// JSON_HEDLEY_DEPRECATED_FOR below does expand to __attribute__((deprecated));
|
||||||
|
// isolated reproductions of this exact declaration shape (doc comment,
|
||||||
|
// template<>, two stacked __attribute__ lines, an overload set of the same
|
||||||
|
// name) do not reproduce it, so this looks like a Clang comment/declaration
|
||||||
|
// association quirk specific to this overload within basic_json, not a
|
||||||
|
// genuine documentation bug. See #5725 item 2.
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdocumentation-deprecated-sync"
|
||||||
|
#endif
|
||||||
template <typename SAX>
|
template <typename SAX>
|
||||||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
|
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
@@ -32002,6 +32078,9 @@ 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(format, sax, strict);
|
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
|
||||||
}
|
}
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
#ifndef JSON_NO_IO
|
#ifndef JSON_NO_IO
|
||||||
/// @brief deserialize from stream
|
/// @brief deserialize from stream
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
|
/// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/
|
||||||
@@ -33422,7 +33501,7 @@ namespace std // NOLINT(cert-dcl58-cpp)
|
|||||||
/// @brief hash value for JSON objects
|
/// @brief hash value for JSON objects
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/std_hash/
|
/// @sa https://json.nlohmann.me/api/basic_json/std_hash/
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
|
struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
{
|
{
|
||||||
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
|
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
|
||||||
{
|
{
|
||||||
@@ -33455,7 +33534,7 @@ struct less< ::nlohmann::detail::value_t> // do not remove the space after '<',
|
|||||||
/// @brief exchanges the values of two JSON objects
|
/// @brief exchanges the values of two JSON objects
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/std_swap/
|
/// @sa https://json.nlohmann.me/api/basic_json/std_swap/
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)
|
inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
|
||||||
is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
|
is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
|
||||||
{
|
{
|
||||||
@@ -33469,7 +33548,7 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC
|
|||||||
/// @brief std::formatter specialization for JSON values
|
/// @brief std::formatter specialization for JSON values
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/std_formatter/
|
/// @sa https://json.nlohmann.me/api/basic_json/std_formatter/
|
||||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-cpp)
|
struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification)
|
||||||
{
|
{
|
||||||
// -1 means compact output (dump()); any value >= 0 means pretty-printed
|
// -1 means compact output (dump()); any value >= 0 means pretty-printed
|
||||||
// output with that many spaces (or indent_char) per level (dump(indent, indent_char)).
|
// output with that many spaces (or indent_char) per level (dump(indent, indent_char)).
|
||||||
@@ -33555,11 +33634,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// restore clang diagnostic settings
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
#undef JSON_ASSERT
|
#undef JSON_ASSERT
|
||||||
#undef JSON_INTERNAL_CATCH
|
#undef JSON_INTERNAL_CATCH
|
||||||
@@ -33759,11 +33833,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// End of GCC diagnostic pragmas for C++ modules support
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The user-defined string literals are in a separate header, because their
|
// The user-defined string literals are in a separate header, because their
|
||||||
// bodies instantiate the parser in every translation unit that includes them.
|
// bodies instantiate the parser in every translation unit that includes them.
|
||||||
// Define JSON_NO_AUTOMATIC_UDLS to include <nlohmann/json_literals.hpp> only
|
// Define JSON_NO_AUTOMATIC_UDLS to include <nlohmann/json_literals.hpp> only
|
||||||
|
|||||||
@@ -90,11 +90,11 @@ target_compile_options(test_main PUBLIC
|
|||||||
# https://github.com/nlohmann/json/pull/3229
|
# https://github.com/nlohmann/json/pull/3229
|
||||||
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
|
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
|
||||||
|
|
||||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||||
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
|
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
|
||||||
|
target_include_directories(test_main SYSTEM PUBLIC
|
||||||
|
thirdparty/doctest)
|
||||||
target_include_directories(test_main PUBLIC
|
target_include_directories(test_main PUBLIC
|
||||||
thirdparty/doctest
|
|
||||||
thirdparty/fifo_map
|
thirdparty/fifo_map
|
||||||
${PROJECT_BINARY_DIR}/include)
|
${PROJECT_BINARY_DIR}/include)
|
||||||
target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME})
|
target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME})
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ target_compile_options(abi_compat_common INTERFACE
|
|||||||
# https://github.com/nlohmann/json/pull/3229
|
# https://github.com/nlohmann/json/pull/3229
|
||||||
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
|
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
|
||||||
|
|
||||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||||
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
|
$<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
|
||||||
target_include_directories(abi_compat_common SYSTEM INTERFACE
|
target_include_directories(abi_compat_common SYSTEM INTERFACE
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ std::string namespace_name(std::string ns, T* /*unused*/ = nullptr) // NOLINT(pe
|
|||||||
std::smatch m;
|
std::smatch m;
|
||||||
|
|
||||||
// extract the true namespace name from the function signature
|
// extract the true namespace name from the function signature
|
||||||
CAPTURE(ns);
|
CAPTURE(ns)
|
||||||
CHECK(std::regex_search(ns, m, std::regex("nlohmann(::[a-zA-Z0-9_]+)*::basic_json")));
|
CHECK(std::regex_search(ns, m, std::regex("nlohmann(::[a-zA-Z0-9_]+)*::basic_json")));
|
||||||
|
|
||||||
return m.str();
|
return m.str();
|
||||||
|
|||||||
@@ -59,10 +59,10 @@ TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test)
|
|||||||
|
|
||||||
INFO("type := ", type_str);
|
INFO("type := ", type_str);
|
||||||
|
|
||||||
CAPTURE(val_min);
|
CAPTURE(val_min)
|
||||||
CAPTURE(min_in_range);
|
CAPTURE(min_in_range)
|
||||||
CAPTURE(val_max);
|
CAPTURE(val_max)
|
||||||
CAPTURE(max_in_range);
|
CAPTURE(max_in_range)
|
||||||
|
|
||||||
if (min_in_range)
|
if (min_in_range)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ TEST_CASE("controlled bad_alloc")
|
|||||||
// iterative path instead, part-way through its worklist.
|
// iterative path instead, part-way through its worklist.
|
||||||
const auto check_deep_copy = [](bool objects)
|
const auto check_deep_copy = [](bool objects)
|
||||||
{
|
{
|
||||||
CAPTURE(objects);
|
CAPTURE(objects)
|
||||||
|
|
||||||
next_construct_fails = false;
|
next_construct_fails = false;
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ struct nth_alloc_fails_allocator : std::allocator<T>
|
|||||||
template<class BasicJsonType>
|
template<class BasicJsonType>
|
||||||
void check_deep_copy_survives_failing_allocation(bool nest_objects)
|
void check_deep_copy_survives_failing_allocation(bool nest_objects)
|
||||||
{
|
{
|
||||||
CAPTURE(nest_objects);
|
CAPTURE(nest_objects)
|
||||||
|
|
||||||
fail_at_alloc_call = -1;
|
fail_at_alloc_call = -1;
|
||||||
|
|
||||||
@@ -352,7 +352,7 @@ void check_deep_copy_survives_failing_allocation(bool nest_objects)
|
|||||||
// must come out exactly as it went in
|
// must come out exactly as it went in
|
||||||
for (std::size_t n = 0; n < total_allocations; ++n)
|
for (std::size_t n = 0; n < total_allocations; ++n)
|
||||||
{
|
{
|
||||||
CAPTURE(n);
|
CAPTURE(n)
|
||||||
alloc_call_count = 0;
|
alloc_call_count = 0;
|
||||||
fail_at_alloc_call = static_cast<long>(n);
|
fail_at_alloc_call = static_cast<long>(n);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wstrict-overflow")
|
|||||||
static int assert_counter;
|
static int assert_counter;
|
||||||
|
|
||||||
/// set failure variable to true instead of calling assert(x)
|
/// set failure variable to true instead of calling assert(x)
|
||||||
#define JSON_ASSERT(x) {if (!(x)) ++assert_counter; }
|
#define JSON_ASSERT(x) do { if (!(x)) { ++assert_counter; } } while (false)
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ TEST_CASE("binary writer output sinks")
|
|||||||
// the first iteration
|
// the first iteration
|
||||||
for (const auto& j : test_values())
|
for (const auto& j : test_values())
|
||||||
{
|
{
|
||||||
CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace));
|
CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace))
|
||||||
|
|
||||||
std::vector<std::uint8_t> cbor;
|
std::vector<std::uint8_t> cbor;
|
||||||
json::to_cbor(j, cbor);
|
json::to_cbor(j, cbor);
|
||||||
@@ -120,8 +120,8 @@ TEST_CASE("binary writer output sinks")
|
|||||||
{
|
{
|
||||||
continue; // not a supported combination
|
continue; // not a supported combination
|
||||||
}
|
}
|
||||||
CAPTURE(use_size);
|
CAPTURE(use_size)
|
||||||
CAPTURE(use_type);
|
CAPTURE(use_type)
|
||||||
std::vector<std::uint8_t> ubjson;
|
std::vector<std::uint8_t> ubjson;
|
||||||
json::to_ubjson(j, ubjson, use_size, use_type);
|
json::to_ubjson(j, ubjson, use_size, use_type);
|
||||||
CHECK(json::to_ubjson(j, use_size, use_type) == ubjson);
|
CHECK(json::to_ubjson(j, use_size, use_type) == ubjson);
|
||||||
@@ -141,7 +141,7 @@ TEST_CASE("binary writer output sinks")
|
|||||||
|
|
||||||
for (const auto& j : bson_values())
|
for (const auto& j : bson_values())
|
||||||
{
|
{
|
||||||
CAPTURE(j.dump());
|
CAPTURE(j.dump())
|
||||||
std::vector<std::uint8_t> bson;
|
std::vector<std::uint8_t> bson;
|
||||||
json::to_bson(j, bson);
|
json::to_bson(j, bson);
|
||||||
CHECK(json::to_bson(j) == bson);
|
CHECK(json::to_bson(j) == bson);
|
||||||
@@ -152,7 +152,7 @@ TEST_CASE("binary writer output sinks")
|
|||||||
{
|
{
|
||||||
for (const auto& j : test_values())
|
for (const auto& j : test_values())
|
||||||
{
|
{
|
||||||
CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace));
|
CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace))
|
||||||
|
|
||||||
const std::vector<std::uint8_t> expected = json::to_cbor(j);
|
const std::vector<std::uint8_t> expected = json::to_cbor(j);
|
||||||
std::vector<char> as_char;
|
std::vector<char> as_char;
|
||||||
@@ -177,7 +177,7 @@ TEST_CASE("binary_reserve_hint never over-reserves")
|
|||||||
{
|
{
|
||||||
for (const auto& j : test_values())
|
for (const auto& j : test_values())
|
||||||
{
|
{
|
||||||
CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace));
|
CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace))
|
||||||
|
|
||||||
const std::size_t hint = nlohmann::detail::binary_reserve_hint(j);
|
const std::size_t hint = nlohmann::detail::binary_reserve_hint(j);
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ TEST_CASE("binary_reserve_hint never over-reserves")
|
|||||||
|
|
||||||
for (const auto& j : bson_values())
|
for (const auto& j : bson_values())
|
||||||
{
|
{
|
||||||
CAPTURE(j.dump());
|
CAPTURE(j.dump())
|
||||||
CHECK(nlohmann::detail::binary_reserve_hint(j) <= json::to_bson(j).size());
|
CHECK(nlohmann::detail::binary_reserve_hint(j) <= json::to_bson(j).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -146,10 +146,10 @@ TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test)
|
|||||||
|
|
||||||
INFO("type := ", type_str);
|
INFO("type := ", type_str);
|
||||||
|
|
||||||
CAPTURE(val_min);
|
CAPTURE(val_min)
|
||||||
CAPTURE(min_in_range);
|
CAPTURE(min_in_range)
|
||||||
CAPTURE(val_max);
|
CAPTURE(val_max)
|
||||||
CAPTURE(max_in_range);
|
CAPTURE(max_in_range)
|
||||||
|
|
||||||
if (min_in_range)
|
if (min_in_range)
|
||||||
{
|
{
|
||||||
@@ -2641,7 +2641,7 @@ TEST_CASE("BJData")
|
|||||||
{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "char"
|
{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "char"
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(type);
|
CAPTURE(type)
|
||||||
const std::string text = std::string(R"({"_ArrayType_":")") + type +
|
const std::string text = std::string(R"({"_ArrayType_":")") + type +
|
||||||
R"(","_ArraySize_":[2,3],"_ArrayData_":[1,2,3,4,5,6]})";
|
R"(","_ArraySize_":[2,3],"_ArrayData_":[1,2,3,4,5,6]})";
|
||||||
const auto from_text = json::to_bjdata(json::parse(text));
|
const auto from_text = json::to_bjdata(json::parse(text));
|
||||||
@@ -2949,7 +2949,7 @@ TEST_CASE("BJData")
|
|||||||
R"({"_ArrayType_":"int16","_ArraySize_":[0,2],"_ArrayData_":[]})"
|
R"({"_ArrayType_":"int16","_ArraySize_":[0,2],"_ArrayData_":[]})"
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(text);
|
CAPTURE(text)
|
||||||
const json j = json::parse(text);
|
const json j = json::parse(text);
|
||||||
for (const bool use_size :
|
for (const bool use_size :
|
||||||
{
|
{
|
||||||
@@ -2983,7 +2983,7 @@ TEST_CASE("BJData")
|
|||||||
R"({"_ArrayType_":"int16","_ArraySize_":[],"_ArrayData_":null})"
|
R"({"_ArrayType_":"int16","_ArraySize_":[],"_ArrayData_":null})"
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(text);
|
CAPTURE(text)
|
||||||
const json j = json::parse(text);
|
const json j = json::parse(text);
|
||||||
const auto out = json::to_bjdata(j);
|
const auto out = json::to_bjdata(j);
|
||||||
CHECK(out.at(0) == '{');
|
CHECK(out.at(0) == '{');
|
||||||
@@ -4317,7 +4317,7 @@ TEST_CASE("BJData and UBJSON can be written to a string")
|
|||||||
|
|
||||||
for (const auto& j : values)
|
for (const auto& j : values)
|
||||||
{
|
{
|
||||||
CAPTURE(j.dump());
|
CAPTURE(j.dump())
|
||||||
for (const bool use_size :
|
for (const bool use_size :
|
||||||
{
|
{
|
||||||
false, true
|
false, true
|
||||||
@@ -4332,8 +4332,8 @@ TEST_CASE("BJData and UBJSON can be written to a string")
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CAPTURE(use_size);
|
CAPTURE(use_size)
|
||||||
CAPTURE(use_type);
|
CAPTURE(use_type)
|
||||||
|
|
||||||
const auto bjdata = json::to_bjdata(j, use_size, use_type);
|
const auto bjdata = json::to_bjdata(j, use_size, use_type);
|
||||||
std::string bjdata_string;
|
std::string bjdata_string;
|
||||||
|
|||||||
@@ -1788,7 +1788,7 @@ TEST_CASE("BSON: deeply nested values")
|
|||||||
json value = "leaf";
|
json value = "leaf";
|
||||||
for (std::size_t depth = 0; depth <= 300; ++depth)
|
for (std::size_t depth = 0; depth <= 300; ++depth)
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
const json document = {{"value", value}, {"n", depth}};
|
const json document = {{"value", value}, {"n", depth}};
|
||||||
CHECK(json::from_bson(json::to_bson(document)) == document);
|
CHECK(json::from_bson(json::to_bson(document)) == document);
|
||||||
|
|
||||||
@@ -1836,7 +1836,7 @@ value = depth % 2 == 0 ? json{{"a", std::move(value)}, {"b", {1, "x"}}} :
|
|||||||
false, true
|
false, true
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(objects);
|
CAPTURE(objects)
|
||||||
std::string text = "{\"a\":";
|
std::string text = "{\"a\":";
|
||||||
for (std::size_t i = 0; i < depth; ++i)
|
for (std::size_t i = 0; i < depth; ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
+30
-30
@@ -17,7 +17,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("boolean")
|
SECTION("boolean")
|
||||||
{
|
{
|
||||||
json j = true; // NOLINT(misc-const-correctness)
|
json j = true;
|
||||||
const json j_const = true;
|
const json j_const = true;
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -35,7 +35,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json j = "hello world"; // NOLINT(misc-const-correctness)
|
json j = "hello world";
|
||||||
const json j_const = "hello world";
|
const json j_const = "hello world";
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -55,7 +55,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("empty array")
|
SECTION("empty array")
|
||||||
{
|
{
|
||||||
json j = json::array(); // NOLINT(misc-const-correctness)
|
json j = json::array();
|
||||||
const json j_const = json::array();
|
const json j_const = json::array();
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -73,7 +73,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("filled array")
|
SECTION("filled array")
|
||||||
{
|
{
|
||||||
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
|
json j = {1, 2, 3};
|
||||||
const json j_const = {1, 2, 3};
|
const json j_const = {1, 2, 3};
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -94,7 +94,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("empty object")
|
SECTION("empty object")
|
||||||
{
|
{
|
||||||
json j = json::object(); // NOLINT(misc-const-correctness)
|
json j = json::object();
|
||||||
const json j_const = json::object();
|
const json j_const = json::object();
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -112,7 +112,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("filled object")
|
SECTION("filled object")
|
||||||
{
|
{
|
||||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
|
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||||
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
|
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -131,7 +131,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (integer)")
|
SECTION("number (integer)")
|
||||||
{
|
{
|
||||||
json j = -23; // NOLINT(misc-const-correctness)
|
json j = -23;
|
||||||
const json j_const = -23;
|
const json j_const = -23;
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -149,7 +149,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (unsigned)")
|
SECTION("number (unsigned)")
|
||||||
{
|
{
|
||||||
json j = 23u; // NOLINT(misc-const-correctness)
|
json j = 23u;
|
||||||
const json j_const = 23u;
|
const json j_const = 23u;
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -167,7 +167,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (float)")
|
SECTION("number (float)")
|
||||||
{
|
{
|
||||||
json j = 23.42; // NOLINT(misc-const-correctness)
|
json j = 23.42;
|
||||||
const json j_const = 23.42;
|
const json j_const = 23.42;
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -185,7 +185,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("null")
|
SECTION("null")
|
||||||
{
|
{
|
||||||
json j = nullptr; // NOLINT(misc-const-correctness)
|
json j = nullptr;
|
||||||
const json j_const = nullptr;
|
const json j_const = nullptr;
|
||||||
|
|
||||||
SECTION("result of empty")
|
SECTION("result of empty")
|
||||||
@@ -206,7 +206,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("boolean")
|
SECTION("boolean")
|
||||||
{
|
{
|
||||||
json j = true; // NOLINT(misc-const-correctness)
|
json j = true;
|
||||||
const json j_const = true;
|
const json j_const = true;
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -226,7 +226,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json j = "hello world"; // NOLINT(misc-const-correctness)
|
json j = "hello world";
|
||||||
const json j_const = "hello world";
|
const json j_const = "hello world";
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -248,7 +248,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("empty array")
|
SECTION("empty array")
|
||||||
{
|
{
|
||||||
json j = json::array(); // NOLINT(misc-const-correctness)
|
json j = json::array();
|
||||||
const json j_const = json::array();
|
const json j_const = json::array();
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -268,7 +268,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("filled array")
|
SECTION("filled array")
|
||||||
{
|
{
|
||||||
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
|
json j = {1, 2, 3};
|
||||||
const json j_const = {1, 2, 3};
|
const json j_const = {1, 2, 3};
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -291,7 +291,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("empty object")
|
SECTION("empty object")
|
||||||
{
|
{
|
||||||
json j = json::object(); // NOLINT(misc-const-correctness)
|
json j = json::object();
|
||||||
const json j_const = json::object();
|
const json j_const = json::object();
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -311,7 +311,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("filled object")
|
SECTION("filled object")
|
||||||
{
|
{
|
||||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
|
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||||
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
|
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -332,7 +332,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (integer)")
|
SECTION("number (integer)")
|
||||||
{
|
{
|
||||||
json j = -23; // NOLINT(misc-const-correctness)
|
json j = -23;
|
||||||
const json j_const = -23;
|
const json j_const = -23;
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -352,7 +352,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (unsigned)")
|
SECTION("number (unsigned)")
|
||||||
{
|
{
|
||||||
json j = 23u; // NOLINT(misc-const-correctness)
|
json j = 23u;
|
||||||
const json j_const = 23u;
|
const json j_const = 23u;
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -372,7 +372,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (float)")
|
SECTION("number (float)")
|
||||||
{
|
{
|
||||||
json j = 23.42; // NOLINT(misc-const-correctness)
|
json j = 23.42;
|
||||||
const json j_const = 23.42;
|
const json j_const = 23.42;
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -392,7 +392,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("null")
|
SECTION("null")
|
||||||
{
|
{
|
||||||
json j = nullptr; // NOLINT(misc-const-correctness)
|
json j = nullptr;
|
||||||
const json j_const = nullptr;
|
const json j_const = nullptr;
|
||||||
|
|
||||||
SECTION("result of size")
|
SECTION("result of size")
|
||||||
@@ -415,7 +415,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("boolean")
|
SECTION("boolean")
|
||||||
{
|
{
|
||||||
json j = true; // NOLINT(misc-const-correctness)
|
json j = true;
|
||||||
const json j_const = true;
|
const json j_const = true;
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -427,7 +427,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json j = "hello world"; // NOLINT(misc-const-correctness)
|
json j = "hello world";
|
||||||
const json j_const = "hello world";
|
const json j_const = "hello world";
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -441,7 +441,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("empty array")
|
SECTION("empty array")
|
||||||
{
|
{
|
||||||
json j = json::array(); // NOLINT(misc-const-correctness)
|
json j = json::array();
|
||||||
const json j_const = json::array();
|
const json j_const = json::array();
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -453,7 +453,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("filled array")
|
SECTION("filled array")
|
||||||
{
|
{
|
||||||
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
|
json j = {1, 2, 3};
|
||||||
const json j_const = {1, 2, 3};
|
const json j_const = {1, 2, 3};
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -468,7 +468,7 @@ TEST_CASE("capacity")
|
|||||||
{
|
{
|
||||||
SECTION("empty object")
|
SECTION("empty object")
|
||||||
{
|
{
|
||||||
json j = json::object(); // NOLINT(misc-const-correctness)
|
json j = json::object();
|
||||||
const json j_const = json::object();
|
const json j_const = json::object();
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -480,7 +480,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("filled object")
|
SECTION("filled object")
|
||||||
{
|
{
|
||||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness)
|
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||||
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
|
const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -493,7 +493,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (integer)")
|
SECTION("number (integer)")
|
||||||
{
|
{
|
||||||
json j = -23; // NOLINT(misc-const-correctness)
|
json j = -23;
|
||||||
const json j_const = -23;
|
const json j_const = -23;
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -505,7 +505,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (unsigned)")
|
SECTION("number (unsigned)")
|
||||||
{
|
{
|
||||||
json j = 23u; // NOLINT(misc-const-correctness)
|
json j = 23u;
|
||||||
const json j_const = 23u;
|
const json j_const = 23u;
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -517,7 +517,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("number (float)")
|
SECTION("number (float)")
|
||||||
{
|
{
|
||||||
json j = 23.42; // NOLINT(misc-const-correctness)
|
json j = 23.42;
|
||||||
const json j_const = 23.42;
|
const json j_const = 23.42;
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
@@ -529,7 +529,7 @@ TEST_CASE("capacity")
|
|||||||
|
|
||||||
SECTION("null")
|
SECTION("null")
|
||||||
{
|
{
|
||||||
json j = nullptr; // NOLINT(misc-const-correctness)
|
json j = nullptr;
|
||||||
const json j_const = nullptr;
|
const json j_const = nullptr;
|
||||||
|
|
||||||
SECTION("result of max_size")
|
SECTION("result of max_size")
|
||||||
|
|||||||
@@ -2931,7 +2931,7 @@ TEST_CASE("Tagged values")
|
|||||||
0xD5, 0xD6, 0xD7
|
0xD5, 0xD6, 0xD7
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(b);
|
CAPTURE(b)
|
||||||
|
|
||||||
// add tag to value
|
// add tag to value
|
||||||
auto v_tagged = v;
|
auto v_tagged = v;
|
||||||
@@ -3271,7 +3271,7 @@ TEST_CASE("CBOR large strings and binaries (chunked reader)")
|
|||||||
std::size_t{4097}, std::size_t{8192}, std::size_t{100000}
|
std::size_t{4097}, std::size_t{8192}, std::size_t{100000}
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(len);
|
CAPTURE(len)
|
||||||
|
|
||||||
// text string
|
// text string
|
||||||
const json j_string = std::string(len, 'x');
|
const json j_string = std::string(len, 'x');
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ TEST_CASE("lexer number fast path")
|
|||||||
std::stringstream ss(doc);
|
std::stringstream ss(doc);
|
||||||
const json b = json::parse(ss);
|
const json b = json::parse(ss);
|
||||||
|
|
||||||
CAPTURE(n);
|
CAPTURE(n)
|
||||||
CHECK(a == b);
|
CHECK(a == b);
|
||||||
CHECK(a.dump() == b.dump());
|
CHECK(a.dump() == b.dump());
|
||||||
CHECK(a[0].type() == b[0].type());
|
CHECK(a[0].type() == b[0].type());
|
||||||
@@ -310,7 +310,7 @@ TEST_CASE("lexer number fast path")
|
|||||||
|
|
||||||
for (const auto& n : numbers)
|
for (const auto& n : numbers)
|
||||||
{
|
{
|
||||||
CAPTURE(n);
|
CAPTURE(n)
|
||||||
const std::string doc = "[" + n + "]";
|
const std::string doc = "[" + n + "]";
|
||||||
|
|
||||||
const json a = json::parse(doc); // contiguous fast path
|
const json a = json::parse(doc); // contiguous fast path
|
||||||
@@ -347,7 +347,7 @@ TEST_CASE("lexer number fast path")
|
|||||||
{"-", "1.", "1e", "1e+", "1.2e", "01", "-01", "1..2", "1.2.3"
|
{"-", "1.", "1e", "1e+", "1.2e", "01", "-01", "1..2", "1.2.3"
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(bad);
|
CAPTURE(bad)
|
||||||
// the contiguous fast path must decline and let the byte path report
|
// the contiguous fast path must decline and let the byte path report
|
||||||
const std::string doc = std::string("[") + bad + "]";
|
const std::string doc = std::string("[") + bad + "]";
|
||||||
CHECK_FALSE(json::accept(doc));
|
CHECK_FALSE(json::accept(doc));
|
||||||
@@ -415,7 +415,7 @@ TEST_CASE("lexer number fast path")
|
|||||||
|
|
||||||
// 7 + 49 + 343 + 2401 tokens
|
// 7 + 49 + 343 + 2401 tokens
|
||||||
CHECK(tokens.size() == 2401);
|
CHECK(tokens.size() == 2401);
|
||||||
CAPTURE(mismatches);
|
CAPTURE(mismatches)
|
||||||
CHECK(mismatches.empty());
|
CHECK(mismatches.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,7 +459,7 @@ TEST_CASE("lexer number fast path")
|
|||||||
"[1 \n2]", "[\n1\n2]", "1\n2", "[01\r\n]", "[1e\n]", "[-\n]"
|
"[1 \n2]", "[\n1\n2]", "1\n2", "[01\r\n]", "[1e\n]", "[-\n]"
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(bad);
|
CAPTURE(bad)
|
||||||
const std::string doc = bad;
|
const std::string doc = bad;
|
||||||
const std::string contiguous_what = contiguous_error(doc);
|
const std::string contiguous_what = contiguous_error(doc);
|
||||||
|
|
||||||
@@ -576,7 +576,7 @@ TEST_CASE("lexer string fast path")
|
|||||||
|
|
||||||
// 13 + 169 + 2197 tokens, each at two offsets
|
// 13 + 169 + 2197 tokens, each at two offsets
|
||||||
CHECK(tokens.size() == 2197);
|
CHECK(tokens.size() == 2197);
|
||||||
CAPTURE(mismatches);
|
CAPTURE(mismatches)
|
||||||
CHECK(mismatches.empty());
|
CHECK(mismatches.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,7 +604,7 @@ TEST_CASE("lexer string fast path")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CAPTURE(mismatches);
|
CAPTURE(mismatches)
|
||||||
CHECK(mismatches.empty());
|
CHECK(mismatches.empty());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -649,10 +649,10 @@ TEST_CASE("lexer string fast path")
|
|||||||
|
|
||||||
for (const auto& test_case : cases)
|
for (const auto& test_case : cases)
|
||||||
{
|
{
|
||||||
CAPTURE(test_case.description);
|
CAPTURE(test_case.description)
|
||||||
for (const std::size_t offset : offsets)
|
for (const std::size_t offset : offsets)
|
||||||
{
|
{
|
||||||
CAPTURE(offset);
|
CAPTURE(offset)
|
||||||
const std::string doc = "[\"" + std::string(offset, 'a') + test_case.sequence + "\"]";
|
const std::string doc = "[\"" + std::string(offset, 'a') + test_case.sequence + "\"]";
|
||||||
CHECK(json::accept(doc) == test_case.valid);
|
CHECK(json::accept(doc) == test_case.valid);
|
||||||
#if !defined(JSON_NOEXCEPTION)
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
@@ -1236,7 +1236,7 @@ TEST_CASE("Eisel-Lemire float conversion")
|
|||||||
|
|
||||||
for (const auto& c : known)
|
for (const auto& c : known)
|
||||||
{
|
{
|
||||||
CAPTURE(c.first);
|
CAPTURE(c.first)
|
||||||
double out = 0;
|
double out = 0;
|
||||||
if (eisel_lemire(c.first, out))
|
if (eisel_lemire(c.first, out))
|
||||||
{
|
{
|
||||||
@@ -1277,7 +1277,7 @@ TEST_CASE("Eisel-Lemire float conversion")
|
|||||||
std::array<char, 64> buffer{};
|
std::array<char, 64> buffer{};
|
||||||
const char* end = nlohmann::detail::to_chars(buffer.data(), buffer.data() + buffer.size(), d);
|
const char* end = nlohmann::detail::to_chars(buffer.data(), buffer.data() + buffer.size(), d);
|
||||||
const std::string token(buffer.data(), static_cast<std::size_t>(end - buffer.data()));
|
const std::string token(buffer.data(), static_cast<std::size_t>(end - buffer.data()));
|
||||||
CAPTURE(token);
|
CAPTURE(token)
|
||||||
double out = 0;
|
double out = 0;
|
||||||
REQUIRE(eisel_lemire(token, out));
|
REQUIRE(eisel_lemire(token, out));
|
||||||
CHECK(bits_of(out) == b);
|
CHECK(bits_of(out) == b);
|
||||||
@@ -1289,7 +1289,7 @@ TEST_CASE("Eisel-Lemire float conversion")
|
|||||||
const std::size_t dot = longer.find('.');
|
const std::size_t dot = longer.find('.');
|
||||||
const std::string extra = dot == std::string::npos ? ".000000000000000000001" : "000000000000000000001";
|
const std::string extra = dot == std::string::npos ? ".000000000000000000001" : "000000000000000000001";
|
||||||
longer.insert(e == std::string::npos ? longer.size() : e, extra);
|
longer.insert(e == std::string::npos ? longer.size() : e, extra);
|
||||||
CAPTURE(longer);
|
CAPTURE(longer)
|
||||||
if (eisel_lemire(longer, out))
|
if (eisel_lemire(longer, out))
|
||||||
{
|
{
|
||||||
CHECK(bits_of(out) == b);
|
CHECK(bits_of(out) == b);
|
||||||
|
|||||||
@@ -2561,7 +2561,7 @@ TEST_CASE("last-read diagnostics are identical across input adapters")
|
|||||||
|
|
||||||
for (const auto& s : inputs)
|
for (const auto& s : inputs)
|
||||||
{
|
{
|
||||||
CAPTURE(s);
|
CAPTURE(s)
|
||||||
|
|
||||||
// reference: contiguous std::string -> seekable (lazy) path
|
// reference: contiguous std::string -> seekable (lazy) path
|
||||||
const std::string reference = parse_error_message(s);
|
const std::string reference = parse_error_message(s);
|
||||||
@@ -2645,7 +2645,7 @@ TEST_CASE("diagnostic positions: value lifetime, input adapters, and SAX")
|
|||||||
|
|
||||||
SECTION("move constructor resets the moved-from value to npos")
|
SECTION("move constructor resets the moved-from value to npos")
|
||||||
{
|
{
|
||||||
// basic_json(basic_json&&) (json.hpp, around line 1265) copies
|
// basic_json(basic_json&&) (json.hpp, around line 1951) copies
|
||||||
// other's start_position/end_position into *this and then resets
|
// other's start_position/end_position into *this and then resets
|
||||||
// other's to npos (see the cppcheck-suppress[accessForwarded]
|
// other's to npos (see the cppcheck-suppress[accessForwarded]
|
||||||
// annotation there, which flags this reset as worth a second
|
// annotation there, which flags this reset as worth a second
|
||||||
|
|||||||
@@ -857,7 +857,7 @@ TEST_CASE("equality of objects whose entries have no fixed order")
|
|||||||
|
|
||||||
for (const std::size_t depth : std::vector<std::size_t> {0, 200})
|
for (const std::size_t depth : std::vector<std::size_t> {0, 200})
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
|
|
||||||
const unordered_json descending = nest(make_unordered_object(true), depth);
|
const unordered_json descending = nest(make_unordered_object(true), depth);
|
||||||
const unordered_json ascending = nest(make_unordered_object(false), depth);
|
const unordered_json ascending = nest(make_unordered_object(false), depth);
|
||||||
@@ -909,7 +909,7 @@ TEST_CASE("equality of an object whose comparator treats different keys as equiv
|
|||||||
|
|
||||||
for (const std::size_t depth : std::vector<std::size_t> {0, 127, 128, 200})
|
for (const std::size_t depth : std::vector<std::size_t> {0, 127, 128, 200})
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
|
|
||||||
const ci_json x = nest(a, depth);
|
const ci_json x = nest(a, depth);
|
||||||
const ci_json y = nest(b, depth);
|
const ci_json y = nest(b, depth);
|
||||||
@@ -935,7 +935,7 @@ TEST_CASE("containers are compared element by element")
|
|||||||
|
|
||||||
for (const std::size_t depth : std::vector<std::size_t> {0, 200})
|
for (const std::size_t depth : std::vector<std::size_t> {0, 200})
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
|
|
||||||
// objects with different keys
|
// objects with different keys
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ TEST_CASE("other constructors and destructor")
|
|||||||
CHECK(j.type() == json::value_t::object);
|
CHECK(j.type() == json::value_t::object);
|
||||||
const json k(std::move(j));
|
const json k(std::move(j));
|
||||||
CHECK(k.type() == json::value_t::object);
|
CHECK(k.type() == json::value_t::object);
|
||||||
CHECK(j.type() == json::value_t::null); // NOLINT: access after move is OK here
|
CHECK(j.type() == json::value_t::null); // NOLINT(bugprone-use-after-move,hicpp-invalid-access-moved) access after move is OK here
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("copy assignment")
|
SECTION("copy assignment")
|
||||||
|
|||||||
@@ -1630,7 +1630,7 @@ TEST_CASE("value conversion")
|
|||||||
|
|
||||||
enum class cards {kreuz, pik, herz, karo};
|
enum class cards {kreuz, pik, herz, karo};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness) - false positive
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM(cards,
|
NLOHMANN_JSON_SERIALIZE_ENUM(cards,
|
||||||
{
|
{
|
||||||
{cards::kreuz, "kreuz"},
|
{cards::kreuz, "kreuz"},
|
||||||
@@ -1648,7 +1648,7 @@ enum TaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppcoreguid
|
|||||||
TS_INVALID = -1,
|
TS_INVALID = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage) - false positive
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
|
NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
|
||||||
{
|
{
|
||||||
{TS_INVALID, nullptr},
|
{TS_INVALID, nullptr},
|
||||||
@@ -1698,7 +1698,7 @@ TEST_CASE("JSON to enum mapping")
|
|||||||
|
|
||||||
enum class strict_cards {kreuz, pik, herz, karo, andere}; // andere not included in mapping
|
enum class strict_cards {kreuz, pik, herz, karo, andere}; // andere not included in mapping
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness) - false positive
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(strict_cards,
|
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(strict_cards,
|
||||||
{
|
{
|
||||||
{strict_cards::kreuz, "kreuz"},
|
{strict_cards::kreuz, "kreuz"},
|
||||||
@@ -1717,7 +1717,7 @@ enum StrictTaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppco
|
|||||||
STRICT_TS_INVALID = -1,
|
STRICT_TS_INVALID = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
|
// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage) - false positive
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(StrictTaskState,
|
NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(StrictTaskState,
|
||||||
{
|
{
|
||||||
{STRICT_TS_INVALID, nullptr},
|
{STRICT_TS_INVALID, nullptr},
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ TEST_CASE("hash of deeply nested values")
|
|||||||
// every depth on either side of where the iterative path takes over
|
// every depth on either side of where the iterative path takes over
|
||||||
for (std::size_t depth = 0; depth <= (2 * nlohmann::detail::recursion_depth_limit()) + 10; ++depth)
|
for (std::size_t depth = 0; depth <= (2 * nlohmann::detail::recursion_depth_limit()) + 10; ++depth)
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
const auto arrays = nested<json>(depth, false);
|
const auto arrays = nested<json>(depth, false);
|
||||||
const auto objects = nested<json>(depth, true);
|
const auto objects = nested<json>(depth, true);
|
||||||
const auto ordered = nested<ordered_json>(depth, true);
|
const auto ordered = nested<ordered_json>(depth, true);
|
||||||
@@ -212,7 +212,7 @@ TEST_CASE("hash of deeply nested values")
|
|||||||
false, true
|
false, true
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(objects);
|
CAPTURE(objects)
|
||||||
const auto text = nested_text(depth, objects);
|
const auto text = nested_text(depth, objects);
|
||||||
const auto a = json::parse(text);
|
const auto a = json::parse(text);
|
||||||
const auto b = json::parse(text);
|
const auto b = json::parse(text);
|
||||||
|
|||||||
@@ -1893,7 +1893,7 @@ TEST_CASE("JSON patch - every operation on ordered_json")
|
|||||||
};
|
};
|
||||||
for (const auto& target : targets)
|
for (const auto& target : targets)
|
||||||
{
|
{
|
||||||
CAPTURE(target.dump());
|
CAPTURE(target.dump())
|
||||||
CHECK(source.patch(ordered_json::diff(source, target)) == target);
|
CHECK(source.patch(ordered_json::diff(source, target)) == target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ TEST_CASE("tests on deeply nested JSONs")
|
|||||||
// are known to meet cleanly - wherever the bound is set.
|
// are known to meet cleanly - wherever the bound is set.
|
||||||
for (std::size_t d = 1; d <= 300; ++d)
|
for (std::size_t d = 1; d <= 300; ++d)
|
||||||
{
|
{
|
||||||
CAPTURE(d);
|
CAPTURE(d)
|
||||||
|
|
||||||
const json array = json::parse(std::string(d, '[') + '0' + std::string(d, ']'));
|
const json array = json::parse(std::string(d, '[') + '0' + std::string(d, ']'));
|
||||||
const json array_copy(array); // NOLINT(performance-unnecessary-copy-initialization): the copy is what is tested
|
const json array_copy(array); // NOLINT(performance-unnecessary-copy-initialization): the copy is what is tested
|
||||||
|
|||||||
@@ -286,8 +286,8 @@ TEST_CASE("locale changes between lexer construction and number conversion (#519
|
|||||||
|
|
||||||
for (const auto& transition : transitions)
|
for (const auto& transition : transitions)
|
||||||
{
|
{
|
||||||
CAPTURE(transition.first);
|
CAPTURE(transition.first)
|
||||||
CAPTURE(transition.second);
|
CAPTURE(transition.second)
|
||||||
|
|
||||||
if (std::setlocale(LC_NUMERIC, transition.first) == nullptr)
|
if (std::setlocale(LC_NUMERIC, transition.first) == nullptr)
|
||||||
{
|
{
|
||||||
@@ -365,7 +365,7 @@ TEST_CASE("locale with a multi-byte decimal point")
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CAPTURE(name);
|
CAPTURE(name)
|
||||||
tested = true;
|
tested = true;
|
||||||
|
|
||||||
// too many significant digits for Clinger's fast path, and an underflow
|
// too many significant digits for Clinger's fast path, and an underflow
|
||||||
|
|||||||
@@ -305,10 +305,10 @@ TEST_CASE("JSON Merge Patch on deeply nested values")
|
|||||||
// over (detail::recursion_depth_limit(), 128)
|
// over (detail::recursion_depth_limit(), 128)
|
||||||
for (std::size_t depth = 0; depth <= 300; ++depth)
|
for (std::size_t depth = 0; depth <= 300; ++depth)
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
for (int variant = 0; variant < 3; ++variant)
|
for (int variant = 0; variant < 3; ++variant)
|
||||||
{
|
{
|
||||||
CAPTURE(variant);
|
CAPTURE(variant)
|
||||||
const json patch = json::parse(nested_objects(depth, variant));
|
const json patch = json::parse(nested_objects(depth, variant));
|
||||||
|
|
||||||
json result = json::parse(nested_objects(depth, (variant + 1) % 3));
|
json result = json::parse(nested_objects(depth, (variant + 1) % 3));
|
||||||
|
|||||||
@@ -1084,10 +1084,10 @@ TEST_CASE("update() on deeply nested values")
|
|||||||
// over (detail::recursion_depth_limit(), 128)
|
// over (detail::recursion_depth_limit(), 128)
|
||||||
for (std::size_t depth = 0; depth <= 300; ++depth)
|
for (std::size_t depth = 0; depth <= 300; ++depth)
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
for (int variant = 0; variant < 3; ++variant)
|
for (int variant = 0; variant < 3; ++variant)
|
||||||
{
|
{
|
||||||
CAPTURE(variant);
|
CAPTURE(variant)
|
||||||
const json source = json::parse(nested_objects(depth, variant));
|
const json source = json::parse(nested_objects(depth, variant));
|
||||||
json result = json::parse(nested_objects(depth, (variant + 1) % 3));
|
json result = json::parse(nested_objects(depth, (variant + 1) % 3));
|
||||||
json expected = result;
|
json expected = result;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION")
|
|||||||
|
|
||||||
for (const auto& test : tests)
|
for (const auto& test : tests)
|
||||||
{
|
{
|
||||||
CAPTURE(test.first);
|
CAPTURE(test.first)
|
||||||
std::istringstream ss(test.first);
|
std::istringstream ss(test.first);
|
||||||
json j;
|
json j;
|
||||||
ss >> j;
|
ss >> j;
|
||||||
@@ -135,7 +135,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION")
|
|||||||
|
|
||||||
for (const auto& test : tests)
|
for (const auto& test : tests)
|
||||||
{
|
{
|
||||||
CAPTURE(test.first);
|
CAPTURE(test.first)
|
||||||
std::istringstream ss(test.first);
|
std::istringstream ss(test.first);
|
||||||
json j;
|
json j;
|
||||||
ss >> j;
|
ss >> j;
|
||||||
@@ -149,7 +149,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION")
|
|||||||
{"1", "12", "-3.5e2", " 7 "
|
{"1", "12", "-3.5e2", " 7 "
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(s);
|
CAPTURE(s)
|
||||||
std::istringstream ss(s);
|
std::istringstream ss(s);
|
||||||
json j;
|
json j;
|
||||||
ss >> j;
|
ss >> j;
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ enum class for_1647
|
|||||||
two
|
two
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays): this is a false positive
|
// NOLINTNEXTLINE(misc-const-correctness): this is a false positive
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
|
NLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
|
||||||
{
|
{
|
||||||
{for_1647::one, "one"},
|
{for_1647::one, "one"},
|
||||||
|
|||||||
@@ -849,13 +849,13 @@ TEST_CASE("issue #5338 - truncated CBOR tagged binary subtype is rejected")
|
|||||||
|
|
||||||
for (const auto& data : truncated_tags)
|
for (const auto& data : truncated_tags)
|
||||||
{
|
{
|
||||||
CAPTURE(data);
|
CAPTURE(data)
|
||||||
for (const auto tag_handler :
|
for (const auto tag_handler :
|
||||||
{
|
{
|
||||||
json::cbor_tag_handler_t::ignore, json::cbor_tag_handler_t::store
|
json::cbor_tag_handler_t::ignore, json::cbor_tag_handler_t::store
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
CAPTURE(tag_handler);
|
CAPTURE(tag_handler)
|
||||||
const auto result = json::from_cbor(data, true, false, tag_handler);
|
const auto result = json::from_cbor(data, true, false, tag_handler);
|
||||||
CHECK(result.is_discarded());
|
CHECK(result.is_discarded());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -584,7 +584,7 @@ TEST_CASE("serialization of deeply nested values")
|
|||||||
// value are known to meet cleanly - wherever the bound is set.
|
// value are known to meet cleanly - wherever the bound is set.
|
||||||
for (std::size_t d = 1; d <= 300; ++d)
|
for (std::size_t d = 1; d <= 300; ++d)
|
||||||
{
|
{
|
||||||
CAPTURE(d);
|
CAPTURE(d)
|
||||||
|
|
||||||
const std::string array_text = std::string(d, '[') + '7' + std::string(d, ']');
|
const std::string array_text = std::string(d, '[') + '7' + std::string(d, ']');
|
||||||
CHECK(json::parse(array_text).dump() == array_text);
|
CHECK(json::parse(array_text).dump() == array_text);
|
||||||
@@ -604,7 +604,7 @@ TEST_CASE("serialization of deeply nested values")
|
|||||||
{
|
{
|
||||||
for (std::size_t d = 120; d <= 140; ++d)
|
for (std::size_t d = 120; d <= 140; ++d)
|
||||||
{
|
{
|
||||||
CAPTURE(d);
|
CAPTURE(d)
|
||||||
|
|
||||||
const json j = json::parse(std::string(d, '[') + '7' + std::string(d, ']'));
|
const json j = json::parse(std::string(d, '[') + '7' + std::string(d, ']'));
|
||||||
|
|
||||||
@@ -629,7 +629,7 @@ TEST_CASE("serialization of deeply nested values")
|
|||||||
// so it must not gain a newline when it is reached iteratively
|
// so it must not gain a newline when it is reached iteratively
|
||||||
for (std::size_t d = 125; d <= 135; ++d)
|
for (std::size_t d = 125; d <= 135; ++d)
|
||||||
{
|
{
|
||||||
CAPTURE(d);
|
CAPTURE(d)
|
||||||
|
|
||||||
const std::string compact = std::string(d, '[') + "[]" + std::string(d, ']');
|
const std::string compact = std::string(d, '[') + "[]" + std::string(d, ']');
|
||||||
CHECK(json::parse(compact).dump() == compact);
|
CHECK(json::parse(compact).dump() == compact);
|
||||||
@@ -711,10 +711,10 @@ TEST_CASE("serialization of every kind of value below the bound of the descent")
|
|||||||
|
|
||||||
for (const std::size_t depth : std::vector<std::size_t> {1, 200})
|
for (const std::size_t depth : std::vector<std::size_t> {1, 200})
|
||||||
{
|
{
|
||||||
CAPTURE(depth);
|
CAPTURE(depth)
|
||||||
for (const auto& inner : values)
|
for (const auto& inner : values)
|
||||||
{
|
{
|
||||||
CAPTURE(inner.dump());
|
CAPTURE(inner.dump())
|
||||||
const json j = wrap_in_arrays(inner, depth);
|
const json j = wrap_in_arrays(inner, depth);
|
||||||
CHECK(j.dump() == std::string(depth, '[') + inner.dump() + std::string(depth, ']'));
|
CHECK(j.dump() == std::string(depth, '[') + inner.dump() + std::string(depth, ']'));
|
||||||
CHECK(j.dump(2) == expected_pretty_in_arrays(inner, depth));
|
CHECK(j.dump(2) == expected_pretty_in_arrays(inner, depth));
|
||||||
@@ -725,7 +725,7 @@ TEST_CASE("serialization of every kind of value below the bound of the descent")
|
|||||||
{
|
{
|
||||||
for (std::size_t d = 120; d <= 140; ++d)
|
for (std::size_t d = 120; d <= 140; ++d)
|
||||||
{
|
{
|
||||||
CAPTURE(d);
|
CAPTURE(d)
|
||||||
|
|
||||||
// built from the inside out: {"k": <level below>, "n": <level>}
|
// built from the inside out: {"k": <level below>, "n": <level>}
|
||||||
json j = 7;
|
json j = 7;
|
||||||
|
|||||||
@@ -350,7 +350,7 @@ TEST_CASE("std::counted_iterator reaches the contiguous fast paths")
|
|||||||
|
|
||||||
for (const auto& text : diagnostic_docs)
|
for (const auto& text : diagnostic_docs)
|
||||||
{
|
{
|
||||||
CAPTURE(text);
|
CAPTURE(text)
|
||||||
const std::counted_iterator<const char*> it(text.data(), static_cast<std::iter_difference_t<const char*>>(text.size()));
|
const std::counted_iterator<const char*> it(text.data(), static_cast<std::iter_difference_t<const char*>>(text.size()));
|
||||||
std::string counted_message;
|
std::string counted_message;
|
||||||
std::string string_message;
|
std::string string_message;
|
||||||
@@ -460,8 +460,8 @@ TEST_CASE("std::counted_iterator bulk scanning stops at the counted end")
|
|||||||
|
|
||||||
for (const auto& tc : cases)
|
for (const auto& tc : cases)
|
||||||
{
|
{
|
||||||
CAPTURE(tc.buffer);
|
CAPTURE(tc.buffer)
|
||||||
CAPTURE(tc.count);
|
CAPTURE(tc.count)
|
||||||
const std::string buffer = tc.buffer;
|
const std::string buffer = tc.buffer;
|
||||||
CHECK(via_counted(buffer, tc.count) == via_prefix(buffer, tc.count));
|
CHECK(via_counted(buffer, tc.count) == via_prefix(buffer, tc.count));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user