Fix lint debt: enum-macro NOLINTs, doctest as SYSTEM, no-op analyzer (#5737)

* Drop stale LCOV_EXCL_LINE from the json_pointer out_of_range.410 throw

The comment said the size_type overflow check in array_index() is only
triggered on special platforms like 32-bit, and the throw was excluded
from coverage. On 64-bit platforms the check is true for SIZE_MAX
itself, and unit-json_pointer.cpp has asserted that case four times
since #5395, so the line is executed in the coverage job. Reword the
comment and remove the exclusion marker so the coverage report notices
if the tests stop reaching it.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Name all three C-array check aliases in the enum-macro NOLINTs

NLOHMANN_JSON_SERIALIZE_ENUM(_STRICT) suppressed the c-array warning
under modernize-avoid-c-arrays only, but clang-tidy emits the same
diagnostic under the aliases cppcoreguidelines-avoid-c-arrays and
hicpp-avoid-c-arrays too. Any user running those checks got a false
positive at every macro expansion, and our own tests needed a local
NOLINT at each call site to work around it.

Name all three aliases in the four macro comments instead, and drop
the now-redundant c-array names from the five test call-site NOLINTs.
Comment-only change; behavior, the public API, and the ABI do not
change. Ran make amalgamate.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Include doctest as a SYSTEM directory instead of disabling warnings for all tests

test_main added -Wno-deprecated and -Wno-float-equal as PUBLIC compile
options for every non-MSVC compiler, so they were applied to every
translation unit, library headers included, and silenced the CI
warnings meant to check the library's own -Wfloat-equal pragmas. The
only code that actually needed the suppression was the vendored
doctest.h, which was included as a normal (non-SYSTEM) directory.

Include thirdparty/doctest as SYSTEM for test_main, matching what
tests/abi/CMakeLists.txt already does, and drop the two suppressions
from both targets. Verified locally that unit-comparison,
unit-conversions and unit-constructor1 compile clean with
-Werror -Weverything and doctest as -isystem, and that CMake still
configures with JSON_BuildTests=ON.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Remove the no-op ci_clang_analyze target

ci_clang_analyze configured the build with the real compiler and only
then wrapped ninja with scan-build. scan-build intercepts compiles by
overriding CC/CXX, but build.ninja already had the compiler path baked
in from the configure step, so every run bypassed the analyzer: CI
logs show "No bugs found" after a normal build, never an analysis.
The job also used Debian's frozen clang-tools-14 rather than the
image's own clang, and CLANG_ANALYZER_CHECKS still named three
valist.* checkers that current clang merged into security.VAList.

ci_clang_tidy already runs every clang-analyzer-* check (via
.clang-tidy's "Checks: '*'") with warnings as errors, so nothing is
lost by removing the dead job. Delete ci_clang_analyze,
CLANG_ANALYZER_CHECKS and the SCAN_BUILD_TOOL lookup from
cmake/ci.cmake, drop it from the ubuntu.yml ci_static_analysis_clang
matrix, and drop the now-unused clang-tools apt package (iwyu stays
for ci_single_binaries). Reword quality_assurance.md and
assurance_case.md, which described the dead job as a working control,
to say the Clang Static Analyzer checks run through clang-tidy.

Verified that `cmake -DJSON_CI=ON` still configures cleanly and that
ci_clang_analyze no longer appears in the generated build or in any
CMake/workflow file.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Re-enable portability-template-virtual-member-function; remove redundant forwards

.clang-tidy disabled three checks "to get the CI going" (#4489,
2024-11-13): portability-template-virtual-member-function,
bugprone-use-after-move and its alias hicpp-invalid-access-moved.

portability-template-virtual-member-function only flagged
output_stream_adapter::write_character/write_characters; annotate
both with NOLINT and re-enable the check.

bugprone-use-after-move flagged several double forwards that have no
effect at runtime:
- from_json.hpp calls std::forward<BasicJsonType>(j).at(Idx) inside
  pack expansions; at() has no ref-qualified overloads and always
  returns an lvalue reference, so the forward is a no-op. Replace with
  plain j.at(Idx) in all four places.
- the move constructor forwards the whole object to its base class
  and then reads other's members. That is item 9 of #5724 (together
  with its cppcheck suppressions) and is left to that change.
- input_adapters.hpp forwards the container twice on purpose, so the
  begin/end iterator types match adapter_type; annotate with NOLINT
  and a comment instead of changing behavior.

The check still flags the move constructor (see above) and two sites
in at(KeyType&&) (both overloads, json.hpp, in the throw's
string_t(std::forward<KeyType>(key)) after
find(std::forward<KeyType>(key))). Open PR #5689 rewrites that hunk,
so bugprone-use-after-move (and hicpp-invalid-access-moved)
stay disabled for now, with a comment explaining why; re-enable them
once #5689 and the #5724 move-constructor change have landed.

Also resolve the portability-avoid-pragma-once TODO: single_include
never has #pragma once (amalgamate.py strips it) and every supported
compiler accepts it in include/, so keep it disabled with an
explanatory comment instead of a TODO. Fix the stale "json.hpp,
around line 1265" comment in unit-class_parser.cpp, which now points
at the move constructor's actual line.

Behavior, the public API and the ABI do not change. Verified with
clang-tidy 22.1.8 that portability-template-virtual-member-function
now reports nothing, that bugprone-use-after-move/
hicpp-invalid-access-moved report only the known at(KeyType&&) and
move-constructor sites, and that unit-custom-base-class, unit-constructor1,
unit-conversions, unit-element_access2, unit-class_parser and
unit-diagnostic-positions (JSON_DIAGNOSTIC_POSITIONS=1) compile
under ASan/UBSan and pass with the same assertion counts as before.
Ran make amalgamate.

Part of #5725

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Fix stale and malformed NOLINT comments

json_sax.hpp named "-warnings-as-errors" in the NOLINT list on the two
JSON_ASSERT(false) lines; that is the suffix clang-tidy appends to a
diagnostic tag under WarningsAsErrors, not a check name, and every
other JSON_ASSERT(false) omits it.

unit-capacity.cpp carried 30 "// NOLINT(misc-const-correctness)"
comments on "json j = ...;" declarations that are all used with
non-const members afterwards, so the check has nothing to report
there.

unit-constructor2.cpp used a blanket "// NOLINT: access after move is
OK here" on a use-after-move that hides every check on the line;
naming bugprone-use-after-move and hicpp-invalid-access-moved keeps
the intent once those checks are re-enabled (#5724).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

#5725 item 10

* Remove stale .clang-tidy entries

-google-runtime-references disabled a check that neither clang-tidy
22.1.8 nor 23.1.2 lists under --list-checks -checks='*'; it was
removed upstream. The commented-out HeaderFilterRegex line has been
unused since the active HeaderFilterRegex was introduced in #2561
(2021).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

#5725 item 11

* Remove the GCC C++20 -Wignored-attributes pragma in json.hpp

The pragma (added in #5164) claimed to work around the C++ modules
redefinition errors of #5103, but #5103 is about hard errors (e.g.
"redefinition of std::__is_constant_evaluated()", conflicting
std::integral_constant) that ignoring a warning cannot suppress; they
are traced to GCC PR 124430 and reproduce with <map> or <string>
instead of json.hpp too. A GCC 16.2 -std=gnu++20 -fmodules build
following #5103's repro steps still fails with the pragma in place,
and a build of all test TUs with GCC_CXXFLAGS (which enable
-Wignored-attributes) and the pragma removed produces no such
warning. The block only hid a warning class from GCC C++20 users
while suggesting #5103 was handled.

Overlaps #5610, whose hunks touch the closing half of this pragma to
insert the json_literals.hpp include.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

#5725 item 9

* Fix stale doxygen comments hidden by the -Wdocumentation pragma

macro_scope.hpp ignores -Wdocumentation and -Wdocumentation-unknown-command
for the whole library, which also hides genuine documentation mistakes:

- detail::unescape() documented "@return unescaped string" but returns
  void and unescapes its argument in place; reworded to
  "@param[in,out] s string to unescape in place" and dropped the
  bogus @return.
- basic_json::get()'s copy-conversion overload wrote "converted to
  @tparam ValueType" inside @return, which Doxygen and Clang parse as
  a second, malformed @tparam; changed to "@a ValueType", matching the
  two other get() overloads a few lines above that already use it.

This narrows the gap the -Wdocumentation pragma needs to cover; fully
replacing the Doxygen-only commands it also hides (item 2c) is left
for after #5267.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

#5725 item 2

* Fix -Wextra-semi-stmt at its actual source, not assert()

clang_flags.cmake blamed the global -Wno-extra-semi-stmt on assert(),
but assert() expands to an expression under glibc and libc++ and does
not trigger this warning. unit-assert_macro.cpp overrides JSON_ASSERT
with "{if (!(x)) ++assert_counter; }", a bare block followed by a
semicolon at every JSON_ASSERT(...) call site in the library; that
was the actual source of 151 of the 208 -Wextra-semi-stmt sites found
in a Clang 22 -Weverything sweep of the test suite with the flag
removed. Switched to the standard do/while(false) macro idiom, which
does not expand to a statement-plus-semicolon, and corrected the
comment to name the remaining source instead: vendored Doctest's
CAPTURE(x) shim, which already ends in a semicolon.

Verified with clang++ -Wextra-semi-stmt (plus the file's other CI
ignores) that unit-assert_macro.cpp now compiles without any
-Wextra-semi-stmt diagnostic.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

#5725 item 8 (step 1 of 2; step 2 covers the CAPTURE() call sites)

* Drop the redundant semicolon from CAPTURE() call sites; remove -Wno-extra-semi-stmt

doctest_compatibility.h defines CAPTURE(x) as DOCTEST_CAPTURE(x); (with
a trailing semicolon baked into the macro), specifically so call sites
do not need to add one themselves; most of the ~267 call sites already
follow that convention. The remaining 64 call sites across 20 files
wrote "CAPTURE(x);" anyway, turning into a statement plus an empty
statement and triggering -Wextra-semi-stmt. Dropped the redundant
semicolon at each of those sites.

With item 6 having already made vendored Doctest a SYSTEM include, and
this the last known source of -Wextra-semi-stmt findings, removed the
flag from clang_flags.cmake entirely.

Verified with clang++ -Wextra-semi-stmt (plus the file's other CI
ignores) that all 20 touched files, plus a file with no CAPTURE() use
(unit-json_pointer.cpp), compile without any -Wextra-semi-stmt
diagnostic.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

#5725 item 8 (step 2 of 2)

* Switch ci_static_analysis_clang off the frozen LLVM 22 dev image

ubuntu.yml pinned the clang-tidy/clang-tidy-sanitizer/single-binaries
job to silkeh/clang:dev, a tag last pushed 2026-02-18 that reports
"clang version 22.0.0 (...+20251015...)", a pre-release snapshot from
before the LLVM 22 release; the maintainer now updates dev-unstable,
22, and latest instead. Switched to silkeh/clang:22, matching the
other clang jobs on :latest.

Verified with clang-tidy 22.1.8 (the image's actual version) against
this repository's .clang-tidy and library headers what the release
image newly reports compared to :dev:

- readability-redundant-typename fires at ~250 sites across the
  _cpp20-relevant conversion/to_chars headers; the library targets
  C++11 and keeps the typenames, so the check is disabled in
  .clang-tidy, matching how the file already handles checks that
  don't fit a C++11 codebase.
- misc-anonymous-namespace-in-header fires on the two anonymous
  namespaces in from_json.hpp and to_json.hpp; added the alias to
  their existing NOLINT (cert-dcl59-cpp, fuchsia-header-anon-namespaces,
  google-build-namespaces).
- bugprone-std-namespace-modification fires on every addition to
  namespace std: the std::hash, std::formatter and std::swap
  overloads in json.hpp, and the std::tuple_size/std::tuple_element
  specializations in iteration_proxy.hpp (this last file is not named
  in #5725's item 5, found by actually running clang-tidy 22.1.8
  against the current tree). All six are legal, deliberate additions
  to namespace std (explicit/partial specializations of std types, or
  the pre-C++20 std::swap overload); annotated each with the check
  name next to its existing cert-dcl58-cpp NOLINT.
- modernize-avoid-c-style-cast reported nothing new.

Also added clang++-22/21, clang-tidy-22/21, g++-16 and gcov-16 to the
find_program search lists in ci.cmake so a local "maximal warnings"
configure prefers the current toolchain version over an older one on
PATH.

#5725 item 5

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Regenerate cmake/gcc_flags.cmake for GCC 16.2.0

GCC_CXXFLAGS was generated for GCC 15.1.0, but ci_test_gcc and
ci_test_gcc_cxx{11..26} now run in gcc:latest, currently GCC 16.2.0,
so the "maximal warnings" job was missing warnings introduced since
15.1.0 while carrying entries GCC 16 treats as duplicates or no-ops.

Regenerated with https://github.com/nlohmann/gcc_flags (patched
locally to not crash on an option whose "-x c++ <opt> -" probe fails
before it reads stdin, e.g. -Wabi=; the tool otherwise raises
BrokenPipeError instead of recording the option as an error) run
against g++ 16.2.0 in the official gcc:16 Docker image, keeping the
documented -Wno-* exclusions and the same alphabetical placement
scheme as before.

Also added three GCC 16 warnings the generator cannot discover on its
own because it only probes value ranges/lists it finds in the -Q
option name itself, not in the enum choices --help=warnings documents
separately:

- -Wbidi-chars=any, -Wleading-whitespace=spaces: manually verified
  these compile cleanly with g++ 16.2.0.
- -Wstrict-flex-arrays: deliberately NOT added, unlike the other two.
  Without -fstrict-flex-arrays (which the library does not enable, as
  it would change codegen for flexible array members), GCC prints
  "'-Wstrict-flex-arrays' is ignored when '-fstrict-flex-arrays' is
  not present" on every translation unit, and under our -Werror that
  note itself aborts the build. This differs from the harmless
  no-op warnings already kept in the file (-Whsa, -Wsynth,
  -Wunreachable-code, -Wunsafe-loop-optimizations), which emit
  nothing; #5725 item 7 named -Wstrict-flex-arrays as one of the
  flags GCC 16 adds, but did not anticipate this failure mode.

Verified: compiled the library header and a representative set of
test translation units (including ones touched by items 1, 3, 8, 9,
10 of this issue) with the regenerated GCC_CXXFLAGS plus -Werror
under g++ 16.2.0 at -std=c++11 through -std=c++26, with zero warnings;
ran the full local test suite (129/129 passing, unrelated to this
compiler) as a regression check. CI must still confirm the actual
ci_test_gcc / ci_test_standards_gcc targets end to end, since this was
verified with direct g++ invocations rather than through the CMake/
CXXFLAGS environment-variable plumbing in ci.cmake.

#5725 item 7

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Avoid std::basic_string<CharType> for non-character output_adapter CharType

output_adapter<CharType, StringType> defaulted StringType to
std::basic_string<CharType>, and (with JSON_NO_IO undefined) always
declared a std::basic_ostream<CharType>&-taking constructor. For
CharType with no non-deprecated std::char_traits specialization (only
std::uint8_t is ever used this way, by the binary writers), simply
naming either type - as an unused default template argument, or as an
unused, never-called constructor's parameter type - instantiates
std::char_traits<CharType> merely to name it, which some standard
libraries mark deprecated: with the library-wide -Wdocumentation
pragma (item 2's other half, left for a later commit) temporarily
removed, an Apple clang 21 / libc++ TU calling json::to_cbor(j, vec)
with std::vector<std::uint8_t>& got one -Wdeprecated-declarations
warning per binary writer at the old output_adapters.hpp:193.

Replaced the eager std::basic_string<CharType> / std::basic_ostream
<CharType> defaults with a bool-tagged partial specialization (not
std::conditional, which requires naming both branches' types up
front regardless of which is selected, reproducing the same warning)
that only ever names std::basic_string<CharType> / std::basic_ostream
<CharType> when CharType is actually one of char, wchar_t, char16_t,
char32_t, or (with __cpp_lib_char8_t) char8_t. For any other
CharType, output_adapter's StringType and ostream-constructor
parameter fall back to two distinct empty placeholder types, kept
distinct so the two constructor overloads do not collide into a
single redeclaration.

Public API / behavior: passing a std::basic_string<std::uint8_t>& or
std::basic_ostream<std::uint8_t>& directly to a binary writer's
output_adapter now fails to compile instead of compiling with a
deprecation warning; this was neither documented nor tested. All
documented uses (std::vector<CharType>, std::basic_ostream<CharType>
and StringType for character CharType) are unaffected.

Verified with Apple clang 21 / libc++, with the two -Wdocumentation*
"ignored" pragma lines in macro_scope.hpp temporarily removed and
-std=c++11/c++20 plus the project's -Weverything flag set: calling
to_cbor/to_msgpack/to_ubjson/to_bjdata/to_bson/to_bon8 on a
std::vector<std::uint8_t> now produces no char_traits<unsigned char>
(or any other) deprecation warning, while the char-based string- and
ostream-adapter paths, and a to_cbor/from_cbor round trip, still
compile and run correctly; also verified with GCC 16.2.0. Ran the
full local test suite, including the binary-format unit tests
(unit-cbor, unit-msgpack, unit-ubjson, unit-bjdata, unit-bson,
unit-bon8, unit-binary_writer_sinks, unit-binary_formats,
unit-custom-binary-type): 129/129 passing.

#5725 item 2 (step a)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Remove the library-wide -Wdocumentation pragma; fix what it hid

macro_scope.hpp / macro_unscope.hpp pushed and popped a Clang
diagnostic region over the entire library that ignored -Wdocumentation
and -Wdocumentation-unknown-command. Removed both pragmas and fixed
every finding a full -Wdocumentation (which implies
-Wdocumentation-unknown-command and -Wdocumentation-deprecated-sync)
build reports, so the library now compiles clean under Clang's
documentation checks without a blanket suppression. Overlaps #5267,
which is still open and edits a nearby doc block (json.hpp's
get()/get_impl() @return, already fixed in the item 2 step (b) commit
of this branch); this commit does not touch that block again.

Unknown Doxygen alias commands (Doxyfile removed in #3071, so these
were never rendered by anything) rewritten as plain prose, keeping the
same information:
- @requirement REQ-JSON-01 / REQ-JSON-02 (iter_impl.hpp,
  json_reverse_iterator.hpp): now "This class satisfies the following
  concept requirements (REQ-JSON-0N):".
- @liveexample{prose,example-id} (three sites in json.hpp): kept the
  prose, dropped the command wrapper and the trailing example-id
  (docs/mkdocs/docs/examples/*.cpp still exist and are used directly
  by the rendered docs, not through this in-header alias) and
  unescaped the "\," commas that were only needed for the old alias's
  comma-separated argument syntax.
- @complexity X (json.hpp x4, json_pointer.hpp x2, serializer.hpp x1):
  now "Complexity: X".

Backslash sequences Clang's comment lexer tried to parse as commands,
escaped to render as literal backslashes:
- lexer.hpp get_codepoint(): two `\u` occurrences.
- binary_reader.hpp get_bson_cstr() / get_bson_cstr_bulk(): two
  `\x00` occurrences.
- serializer.hpp: three `\uXXXX` occurrences (constructor @param,
  append_codepoint_to_string_buffer() @brief, and the ensure_ascii
  member comment).

One finding remained after all of the above: Clang reports
"declaration is marked with '@deprecated' command but does not have a
deprecation attribute" on the deprecated sax_parse(span_input_adapter&&, ...)
overload, even though JSON_HEDLEY_DEPRECATED_FOR does expand to
__attribute__((deprecated(...))) for Clang. Several isolated
reproductions of this exact declaration shape - doc comment,
template<>, two stacked __attribute__ macros, an overload set sharing
the name - did not reproduce the warning, so this looks like a
Clang comment/declaration-association quirk specific to this overload
inside the much larger basic_json class template, not an actual
documentation defect. Rather than keep the pragma library-wide for one
Clang false positive, added a tightly scoped
-Wdocumentation-deprecated-sync push/pop around just that overload.

Verified with Apple clang 21 and the project's actual -Weverything
flag set (cmake/clang_flags.cmake) on the full header at -std=c++11
and -std=c++20: zero -Wdocumentation* diagnostics. Also compiled
clean with GCC 16.2.0 (the pragmas are already __clang__-gated, so
this only confirms no unrelated breakage). Ran make check-amalgamation
and the full local test suite: 129/129 passing.

#5725 item 2 (step c)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Take the JSON value by const reference in the array and tuple from_json paths

Review feedback on #5737 (gregmarr): once the no-op std::forward calls
are gone, the forwarding references have no purpose. from_json_fn
passes the value as const BasicJsonType&, so these functions were only
ever instantiated with a const lvalue anyway.

The std::array, std::pair and std::tuple overloads of from_json and
their helpers now take const BasicJsonType& and pass j on unchanged.
Because the deduced BasicJsonType is now the plain type, tuple_type and
the static_assert name const BasicJsonType& explicitly, so the
reference checks are unchanged: get<std::tuple<const std::string&>>()
still works, and get<std::tuple<std::string&>>() still fails the same
static_assert. from_json_tuple_get_impl keeps its forwarding reference,
since tuple_type calls it through std::declval.

Behavior, the public API and the ABI do not change. unit-conversions,
unit-constructor1, unit-udt, unit-udt_macro, unit-regression1/2/3,
unit-deserialization, unit-noexcept, unit-items, unit-allocator,
unit-custom-object-type, unit-ordered_json2 and
unit-brace-init-copy-semantics pass at C++11, C++17 and C++20 with
unchanged assertion counts. Ran make amalgamate.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-10-01 07:37:47 +02:00
committed by GitHub
parent b54ed188e6
commit e5a89d671f
47 changed files with 321 additions and 239 deletions
+3 -3
View File
@@ -239,7 +239,7 @@ TEST_CASE("controlled bad_alloc")
// iterative path instead, part-way through its worklist.
const auto check_deep_copy = [](bool objects)
{
CAPTURE(objects);
CAPTURE(objects)
next_construct_fails = false;
@@ -315,7 +315,7 @@ struct nth_alloc_fails_allocator : std::allocator<T>
template<class BasicJsonType>
void check_deep_copy_survives_failing_allocation(bool nest_objects)
{
CAPTURE(nest_objects);
CAPTURE(nest_objects)
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
for (std::size_t n = 0; n < total_allocations; ++n)
{
CAPTURE(n);
CAPTURE(n)
alloc_call_count = 0;
fail_at_alloc_call = static_cast<long>(n);
+1 -1
View File
@@ -18,7 +18,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wstrict-overflow")
static int assert_counter;
/// 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>
using nlohmann::json;
+7 -7
View File
@@ -89,7 +89,7 @@ TEST_CASE("binary writer output sinks")
// the first iteration
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;
json::to_cbor(j, cbor);
@@ -120,8 +120,8 @@ TEST_CASE("binary writer output sinks")
{
continue; // not a supported combination
}
CAPTURE(use_size);
CAPTURE(use_type);
CAPTURE(use_size)
CAPTURE(use_type)
std::vector<std::uint8_t> ubjson;
json::to_ubjson(j, ubjson, use_size, use_type);
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())
{
CAPTURE(j.dump());
CAPTURE(j.dump())
std::vector<std::uint8_t> bson;
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())
{
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);
std::vector<char> as_char;
@@ -177,7 +177,7 @@ TEST_CASE("binary_reserve_hint never over-reserves")
{
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);
@@ -194,7 +194,7 @@ TEST_CASE("binary_reserve_hint never over-reserves")
for (const auto& j : bson_values())
{
CAPTURE(j.dump());
CAPTURE(j.dump())
CHECK(nlohmann::detail::binary_reserve_hint(j) <= json::to_bson(j).size());
}
+6 -6
View File
@@ -2523,7 +2523,7 @@ TEST_CASE("BJData")
{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "char"
})
{
CAPTURE(type);
CAPTURE(type)
const std::string text = std::string(R"({"_ArrayType_":")") + type +
R"(","_ArraySize_":[2,3],"_ArrayData_":[1,2,3,4,5,6]})";
const auto from_text = json::to_bjdata(json::parse(text));
@@ -2831,7 +2831,7 @@ TEST_CASE("BJData")
R"({"_ArrayType_":"int16","_ArraySize_":[0,2],"_ArrayData_":[]})"
})
{
CAPTURE(text);
CAPTURE(text)
const json j = json::parse(text);
for (const bool use_size :
{
@@ -2865,7 +2865,7 @@ TEST_CASE("BJData")
R"({"_ArrayType_":"int16","_ArraySize_":[],"_ArrayData_":null})"
})
{
CAPTURE(text);
CAPTURE(text)
const json j = json::parse(text);
const auto out = json::to_bjdata(j);
CHECK(out.at(0) == '{');
@@ -4199,7 +4199,7 @@ TEST_CASE("BJData and UBJSON can be written to a string")
for (const auto& j : values)
{
CAPTURE(j.dump());
CAPTURE(j.dump())
for (const bool use_size :
{
false, true
@@ -4214,8 +4214,8 @@ TEST_CASE("BJData and UBJSON can be written to a string")
{
continue;
}
CAPTURE(use_size);
CAPTURE(use_type);
CAPTURE(use_size)
CAPTURE(use_type)
const auto bjdata = json::to_bjdata(j, use_size, use_type);
std::string bjdata_string;
+2 -2
View File
@@ -1752,7 +1752,7 @@ TEST_CASE("BSON: deeply nested values")
json value = "leaf";
for (std::size_t depth = 0; depth <= 300; ++depth)
{
CAPTURE(depth);
CAPTURE(depth)
const json document = {{"value", value}, {"n", depth}};
CHECK(json::from_bson(json::to_bson(document)) == document);
@@ -1800,7 +1800,7 @@ value = depth % 2 == 0 ? json{{"a", std::move(value)}, {"b", {1, "x"}}} :
false, true
})
{
CAPTURE(objects);
CAPTURE(objects)
std::string text = "{\"a\":";
for (std::size_t i = 0; i < depth; ++i)
{
+30 -30
View File
@@ -17,7 +17,7 @@ TEST_CASE("capacity")
{
SECTION("boolean")
{
json j = true; // NOLINT(misc-const-correctness)
json j = true;
const json j_const = true;
SECTION("result of empty")
@@ -35,7 +35,7 @@ TEST_CASE("capacity")
SECTION("string")
{
json j = "hello world"; // NOLINT(misc-const-correctness)
json j = "hello world";
const json j_const = "hello world";
SECTION("result of empty")
@@ -55,7 +55,7 @@ TEST_CASE("capacity")
{
SECTION("empty array")
{
json j = json::array(); // NOLINT(misc-const-correctness)
json j = json::array();
const json j_const = json::array();
SECTION("result of empty")
@@ -73,7 +73,7 @@ TEST_CASE("capacity")
SECTION("filled array")
{
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
json j = {1, 2, 3};
const json j_const = {1, 2, 3};
SECTION("result of empty")
@@ -94,7 +94,7 @@ TEST_CASE("capacity")
{
SECTION("empty object")
{
json j = json::object(); // NOLINT(misc-const-correctness)
json j = json::object();
const json j_const = json::object();
SECTION("result of empty")
@@ -112,7 +112,7 @@ TEST_CASE("capacity")
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}};
SECTION("result of empty")
@@ -131,7 +131,7 @@ TEST_CASE("capacity")
SECTION("number (integer)")
{
json j = -23; // NOLINT(misc-const-correctness)
json j = -23;
const json j_const = -23;
SECTION("result of empty")
@@ -149,7 +149,7 @@ TEST_CASE("capacity")
SECTION("number (unsigned)")
{
json j = 23u; // NOLINT(misc-const-correctness)
json j = 23u;
const json j_const = 23u;
SECTION("result of empty")
@@ -167,7 +167,7 @@ TEST_CASE("capacity")
SECTION("number (float)")
{
json j = 23.42; // NOLINT(misc-const-correctness)
json j = 23.42;
const json j_const = 23.42;
SECTION("result of empty")
@@ -185,7 +185,7 @@ TEST_CASE("capacity")
SECTION("null")
{
json j = nullptr; // NOLINT(misc-const-correctness)
json j = nullptr;
const json j_const = nullptr;
SECTION("result of empty")
@@ -206,7 +206,7 @@ TEST_CASE("capacity")
{
SECTION("boolean")
{
json j = true; // NOLINT(misc-const-correctness)
json j = true;
const json j_const = true;
SECTION("result of size")
@@ -226,7 +226,7 @@ TEST_CASE("capacity")
SECTION("string")
{
json j = "hello world"; // NOLINT(misc-const-correctness)
json j = "hello world";
const json j_const = "hello world";
SECTION("result of size")
@@ -248,7 +248,7 @@ TEST_CASE("capacity")
{
SECTION("empty array")
{
json j = json::array(); // NOLINT(misc-const-correctness)
json j = json::array();
const json j_const = json::array();
SECTION("result of size")
@@ -268,7 +268,7 @@ TEST_CASE("capacity")
SECTION("filled array")
{
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
json j = {1, 2, 3};
const json j_const = {1, 2, 3};
SECTION("result of size")
@@ -291,7 +291,7 @@ TEST_CASE("capacity")
{
SECTION("empty object")
{
json j = json::object(); // NOLINT(misc-const-correctness)
json j = json::object();
const json j_const = json::object();
SECTION("result of size")
@@ -311,7 +311,7 @@ TEST_CASE("capacity")
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}};
SECTION("result of size")
@@ -332,7 +332,7 @@ TEST_CASE("capacity")
SECTION("number (integer)")
{
json j = -23; // NOLINT(misc-const-correctness)
json j = -23;
const json j_const = -23;
SECTION("result of size")
@@ -352,7 +352,7 @@ TEST_CASE("capacity")
SECTION("number (unsigned)")
{
json j = 23u; // NOLINT(misc-const-correctness)
json j = 23u;
const json j_const = 23u;
SECTION("result of size")
@@ -372,7 +372,7 @@ TEST_CASE("capacity")
SECTION("number (float)")
{
json j = 23.42; // NOLINT(misc-const-correctness)
json j = 23.42;
const json j_const = 23.42;
SECTION("result of size")
@@ -392,7 +392,7 @@ TEST_CASE("capacity")
SECTION("null")
{
json j = nullptr; // NOLINT(misc-const-correctness)
json j = nullptr;
const json j_const = nullptr;
SECTION("result of size")
@@ -415,7 +415,7 @@ TEST_CASE("capacity")
{
SECTION("boolean")
{
json j = true; // NOLINT(misc-const-correctness)
json j = true;
const json j_const = true;
SECTION("result of max_size")
@@ -427,7 +427,7 @@ TEST_CASE("capacity")
SECTION("string")
{
json j = "hello world"; // NOLINT(misc-const-correctness)
json j = "hello world";
const json j_const = "hello world";
SECTION("result of max_size")
@@ -441,7 +441,7 @@ TEST_CASE("capacity")
{
SECTION("empty array")
{
json j = json::array(); // NOLINT(misc-const-correctness)
json j = json::array();
const json j_const = json::array();
SECTION("result of max_size")
@@ -453,7 +453,7 @@ TEST_CASE("capacity")
SECTION("filled array")
{
json j = {1, 2, 3}; // NOLINT(misc-const-correctness)
json j = {1, 2, 3};
const json j_const = {1, 2, 3};
SECTION("result of max_size")
@@ -468,7 +468,7 @@ TEST_CASE("capacity")
{
SECTION("empty object")
{
json j = json::object(); // NOLINT(misc-const-correctness)
json j = json::object();
const json j_const = json::object();
SECTION("result of max_size")
@@ -480,7 +480,7 @@ TEST_CASE("capacity")
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}};
SECTION("result of max_size")
@@ -493,7 +493,7 @@ TEST_CASE("capacity")
SECTION("number (integer)")
{
json j = -23; // NOLINT(misc-const-correctness)
json j = -23;
const json j_const = -23;
SECTION("result of max_size")
@@ -505,7 +505,7 @@ TEST_CASE("capacity")
SECTION("number (unsigned)")
{
json j = 23u; // NOLINT(misc-const-correctness)
json j = 23u;
const json j_const = 23u;
SECTION("result of max_size")
@@ -517,7 +517,7 @@ TEST_CASE("capacity")
SECTION("number (float)")
{
json j = 23.42; // NOLINT(misc-const-correctness)
json j = 23.42;
const json j_const = 23.42;
SECTION("result of max_size")
@@ -529,7 +529,7 @@ TEST_CASE("capacity")
SECTION("null")
{
json j = nullptr; // NOLINT(misc-const-correctness)
json j = nullptr;
const json j_const = nullptr;
SECTION("result of max_size")
+2 -2
View File
@@ -2878,7 +2878,7 @@ TEST_CASE("Tagged values")
0xD5, 0xD6, 0xD7
})
{
CAPTURE(b);
CAPTURE(b)
// add tag to value
auto v_tagged = v;
@@ -3218,7 +3218,7 @@ TEST_CASE("CBOR large strings and binaries (chunked reader)")
std::size_t{4097}, std::size_t{8192}, std::size_t{100000}
})
{
CAPTURE(len);
CAPTURE(len)
// text string
const json j_string = std::string(len, 'x');
+12 -12
View File
@@ -272,7 +272,7 @@ TEST_CASE("lexer number fast path")
std::stringstream ss(doc);
const json b = json::parse(ss);
CAPTURE(n);
CAPTURE(n)
CHECK(a == b);
CHECK(a.dump() == b.dump());
CHECK(a[0].type() == b[0].type());
@@ -310,7 +310,7 @@ TEST_CASE("lexer number fast path")
for (const auto& n : numbers)
{
CAPTURE(n);
CAPTURE(n)
const std::string doc = "[" + n + "]";
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"
})
{
CAPTURE(bad);
CAPTURE(bad)
// the contiguous fast path must decline and let the byte path report
const std::string doc = std::string("[") + bad + "]";
CHECK_FALSE(json::accept(doc));
@@ -415,7 +415,7 @@ TEST_CASE("lexer number fast path")
// 7 + 49 + 343 + 2401 tokens
CHECK(tokens.size() == 2401);
CAPTURE(mismatches);
CAPTURE(mismatches)
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]"
})
{
CAPTURE(bad);
CAPTURE(bad)
const std::string doc = bad;
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
CHECK(tokens.size() == 2197);
CAPTURE(mismatches);
CAPTURE(mismatches)
CHECK(mismatches.empty());
}
@@ -604,7 +604,7 @@ TEST_CASE("lexer string fast path")
}
}
}
CAPTURE(mismatches);
CAPTURE(mismatches)
CHECK(mismatches.empty());
}
#endif
@@ -649,10 +649,10 @@ TEST_CASE("lexer string fast path")
for (const auto& test_case : cases)
{
CAPTURE(test_case.description);
CAPTURE(test_case.description)
for (const std::size_t offset : offsets)
{
CAPTURE(offset);
CAPTURE(offset)
const std::string doc = "[\"" + std::string(offset, 'a') + test_case.sequence + "\"]";
CHECK(json::accept(doc) == test_case.valid);
#if !defined(JSON_NOEXCEPTION)
@@ -1236,7 +1236,7 @@ TEST_CASE("Eisel-Lemire float conversion")
for (const auto& c : known)
{
CAPTURE(c.first);
CAPTURE(c.first)
double out = 0;
if (eisel_lemire(c.first, out))
{
@@ -1277,7 +1277,7 @@ TEST_CASE("Eisel-Lemire float conversion")
std::array<char, 64> buffer{};
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()));
CAPTURE(token);
CAPTURE(token)
double out = 0;
REQUIRE(eisel_lemire(token, out));
CHECK(bits_of(out) == b);
@@ -1289,7 +1289,7 @@ TEST_CASE("Eisel-Lemire float conversion")
const std::size_t dot = longer.find('.');
const std::string extra = dot == std::string::npos ? ".000000000000000000001" : "000000000000000000001";
longer.insert(e == std::string::npos ? longer.size() : e, extra);
CAPTURE(longer);
CAPTURE(longer)
if (eisel_lemire(longer, out))
{
CHECK(bits_of(out) == b);
+2 -2
View File
@@ -2561,7 +2561,7 @@ TEST_CASE("last-read diagnostics are identical across input adapters")
for (const auto& s : inputs)
{
CAPTURE(s);
CAPTURE(s)
// reference: contiguous std::string -> seekable (lazy) path
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")
{
// 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 to npos (see the cppcheck-suppress[accessForwarded]
// annotation there, which flags this reset as worth a second
+3 -3
View File
@@ -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})
{
CAPTURE(depth);
CAPTURE(depth)
const unordered_json descending = nest(make_unordered_object(true), 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})
{
CAPTURE(depth);
CAPTURE(depth)
const ci_json x = nest(a, 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})
{
CAPTURE(depth);
CAPTURE(depth)
// objects with different keys
{
+1 -1
View File
@@ -85,7 +85,7 @@ TEST_CASE("other constructors and destructor")
CHECK(j.type() == json::value_t::object);
const json k(std::move(j));
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")
+4 -4
View File
@@ -1640,7 +1640,7 @@ TEST_CASE("value conversion")
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,
{
{cards::kreuz, "kreuz"},
@@ -1658,7 +1658,7 @@ enum TaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppcoreguid
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,
{
{TS_INVALID, nullptr},
@@ -1708,7 +1708,7 @@ TEST_CASE("JSON to enum 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,
{
{strict_cards::kreuz, "kreuz"},
@@ -1727,7 +1727,7 @@ enum StrictTaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppco
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,
{
{STRICT_TS_INVALID, nullptr},
+2 -2
View File
@@ -191,7 +191,7 @@ TEST_CASE("hash of deeply nested values")
// 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)
{
CAPTURE(depth);
CAPTURE(depth)
const auto arrays = nested<json>(depth, false);
const auto objects = nested<json>(depth, true);
const auto ordered = nested<ordered_json>(depth, true);
@@ -212,7 +212,7 @@ TEST_CASE("hash of deeply nested values")
false, true
})
{
CAPTURE(objects);
CAPTURE(objects)
const auto text = nested_text(depth, objects);
const auto a = json::parse(text);
const auto b = json::parse(text);
+6 -6
View File
@@ -1829,13 +1829,13 @@ TEST_CASE("JSON patch: diff of deeply nested values")
for (const auto depth : depths)
{
CAPTURE(depth);
CAPTURE(depth)
for (int from = 0; from < 3; ++from)
{
for (int to = 0; to < 3; ++to)
{
CAPTURE(from);
CAPTURE(to);
CAPTURE(from)
CAPTURE(to)
const auto source = nested<json>(depth, from);
const auto target = nested<json>(depth, to);
const auto patch = json::diff(source, target);
@@ -1854,7 +1854,7 @@ TEST_CASE("JSON patch: diff of deeply nested values")
{
for (std::size_t depth = 0; depth <= 300; ++depth)
{
CAPTURE(depth);
CAPTURE(depth)
json source = 1;
json target = 2;
for (std::size_t i = 0; i < depth; ++i)
@@ -1878,7 +1878,7 @@ TEST_CASE("JSON patch: diff of deeply nested values")
false, true
})
{
CAPTURE(objects);
CAPTURE(objects)
std::string source_text;
std::string target_text;
std::string equal_text;
@@ -2046,7 +2046,7 @@ TEST_CASE("JSON patch - every operation on ordered_json")
};
for (const auto& target : targets)
{
CAPTURE(target.dump());
CAPTURE(target.dump())
CHECK(source.patch(ordered_json::diff(source, target)) == target);
}
}
+6 -6
View File
@@ -135,7 +135,7 @@ TEST_CASE("tests on deeply nested JSONs")
// are known to meet cleanly - wherever the bound is set.
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_copy(array); // NOLINT(performance-unnecessary-copy-initialization): the copy is what is tested
@@ -252,7 +252,7 @@ TEST_CASE("tests on deeply nested JSONs")
{
for (const auto& pattern : patterns)
{
CAPTURE(pattern);
CAPTURE(pattern)
const std::string text = nested_text(depth, pattern);
const json j = json::parse(text);
@@ -265,7 +265,7 @@ TEST_CASE("tests on deeply nested JSONs")
{
for (const auto& pattern : patterns)
{
CAPTURE(pattern);
CAPTURE(pattern)
const std::string text = nested_text(depth, pattern);
const nlohmann::ordered_json o = nlohmann::ordered_json::parse(text);
@@ -278,7 +278,7 @@ TEST_CASE("tests on deeply nested JSONs")
{
for (const auto& pattern : patterns)
{
CAPTURE(pattern);
CAPTURE(pattern)
const std::string text = nested_text(depth, pattern);
const json j = json::parse(text);
@@ -290,10 +290,10 @@ TEST_CASE("tests on deeply nested JSONs")
{
for (std::size_t d = 1; d <= 300; ++d)
{
CAPTURE(d);
CAPTURE(d)
for (const auto& pattern : patterns)
{
CAPTURE(pattern);
CAPTURE(pattern)
const std::string text = nested_text(d, pattern);
const json j = json::parse(text);
+3 -3
View File
@@ -289,8 +289,8 @@ TEST_CASE("locale changes between lexer construction and number conversion (#519
for (const auto& transition : transitions)
{
CAPTURE(transition.first);
CAPTURE(transition.second);
CAPTURE(transition.first)
CAPTURE(transition.second)
if (std::setlocale(LC_NUMERIC, transition.first) == nullptr)
{
@@ -368,7 +368,7 @@ TEST_CASE("locale with a multi-byte decimal point")
{
continue;
}
CAPTURE(name);
CAPTURE(name)
tested = true;
// too many significant digits for Clinger's fast path, and an underflow
+3 -3
View File
@@ -305,10 +305,10 @@ TEST_CASE("JSON Merge Patch on deeply nested values")
// over (detail::recursion_depth_limit(), 128)
for (std::size_t depth = 0; depth <= 300; ++depth)
{
CAPTURE(depth);
CAPTURE(depth)
for (int variant = 0; variant < 3; ++variant)
{
CAPTURE(variant);
CAPTURE(variant)
const json patch = json::parse(nested_objects(depth, variant));
json result = json::parse(nested_objects(depth, (variant + 1) % 3));
@@ -403,7 +403,7 @@ TEST_CASE("merge_patch() with an argument that aliases *this (#5641)")
std::size_t{0}, std::size_t{127}, std::size_t{128}, std::size_t{300}
})
{
CAPTURE(depth);
CAPTURE(depth)
json j = json::parse(nested_objects(depth, 0));
const json expected = j;
j.merge_patch(j);
+3 -3
View File
@@ -1084,10 +1084,10 @@ TEST_CASE("update() on deeply nested values")
// over (detail::recursion_depth_limit(), 128)
for (std::size_t depth = 0; depth <= 300; ++depth)
{
CAPTURE(depth);
CAPTURE(depth)
for (int variant = 0; variant < 3; ++variant)
{
CAPTURE(variant);
CAPTURE(variant)
const json source = json::parse(nested_objects(depth, variant));
json result = json::parse(nested_objects(depth, (variant + 1) % 3));
json expected = result;
@@ -1177,7 +1177,7 @@ TEST_CASE("update() with an argument that aliases *this (#5641)")
std::size_t{0}, std::size_t{127}, std::size_t{128}, std::size_t{300}
})
{
CAPTURE(depth);
CAPTURE(depth)
json j = json::parse(nested_objects(depth, 0));
const json expected = j;
j.update(j, true);
+3 -3
View File
@@ -113,7 +113,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION")
for (const auto& test : tests)
{
CAPTURE(test.first);
CAPTURE(test.first)
std::istringstream ss(test.first);
json j;
ss >> j;
@@ -135,7 +135,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION")
for (const auto& test : tests)
{
CAPTURE(test.first);
CAPTURE(test.first)
std::istringstream ss(test.first);
json j;
ss >> j;
@@ -149,7 +149,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION")
{"1", "12", "-3.5e2", " 7 "
})
{
CAPTURE(s);
CAPTURE(s)
std::istringstream ss(s);
json j;
ss >> j;
+1 -1
View File
@@ -126,7 +126,7 @@ enum class for_1647
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,
{
{for_1647::one, "one"},
+2 -2
View File
@@ -849,13 +849,13 @@ TEST_CASE("issue #5338 - truncated CBOR tagged binary subtype is rejected")
for (const auto& data : truncated_tags)
{
CAPTURE(data);
CAPTURE(data)
for (const auto tag_handler :
{
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);
CHECK(result.is_discarded());
}
+6 -6
View File
@@ -584,7 +584,7 @@ TEST_CASE("serialization of deeply nested values")
// value are known to meet cleanly - wherever the bound is set.
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, ']');
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)
{
CAPTURE(d);
CAPTURE(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
for (std::size_t d = 125; d <= 135; ++d)
{
CAPTURE(d);
CAPTURE(d)
const std::string compact = std::string(d, '[') + "[]" + std::string(d, ']');
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})
{
CAPTURE(depth);
CAPTURE(depth)
for (const auto& inner : values)
{
CAPTURE(inner.dump());
CAPTURE(inner.dump())
const json j = wrap_in_arrays(inner, depth);
CHECK(j.dump() == std::string(depth, '[') + inner.dump() + std::string(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)
{
CAPTURE(d);
CAPTURE(d)
// built from the inside out: {"k": <level below>, "n": <level>}
json j = 7;
+3 -3
View File
@@ -350,7 +350,7 @@ TEST_CASE("std::counted_iterator reaches the contiguous fast paths")
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()));
std::string counted_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)
{
CAPTURE(tc.buffer);
CAPTURE(tc.count);
CAPTURE(tc.buffer)
CAPTURE(tc.count)
const std::string buffer = tc.buffer;
CHECK(via_counted(buffer, tc.count) == via_prefix(buffer, tc.count));
}
+4 -4
View File
@@ -63,10 +63,10 @@ TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test)
INFO("type := ", type_str);
CAPTURE(val_min);
CAPTURE(min_in_range);
CAPTURE(val_max);
CAPTURE(max_in_range);
CAPTURE(val_min)
CAPTURE(min_in_range)
CAPTURE(val_max)
CAPTURE(max_in_range)
if (min_in_range)
{