Compare commits

..
Author SHA1 Message Date
Niels Lohmann d7a7534872 Tests: skip the parse() allocation sweep with MSVC iterator debugging
With _ITERATOR_DEBUG_LEVEL > 0 (MSVC STL debug builds, clang-cl), containers
allocate inside noexcept functions, so a failing allocation terminates the
program: "test case CRASHED: Terminate handler called" in the sax_parse
subcase of #5985. The sweep test of #6000 has the same guard.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 19:12:26 +01:00
Niels Lohmann eaee875178 json_view: no constant operand in the number dispatch (MSVC C4127)
The `!negative ||` that #6006 added to the digit test of the number scan has
a constant left operand in the template (negative is a template argument), so
MSVC reports C4127 under /WX in builder.hpp(1177). Restore the plain test; the
branch behaves the same.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 19:12:26 +01:00
Niels Lohmann 3724295333 json_view: a value that is not found has no bytes in its exception context
Keeping the byte range of the root value (#5990) dropped the found flag of
value_path(), but a root has no tokens and is found, while a view of a value
that was removed from the document is not found. Without the flag, the
removed value got the bytes of its stale node, and
"json_view exceptions name the path and the bytes of the value" failed on
the macOS jobs with JSON_DIAGNOSTICS and JSON_DIAGNOSTIC_POSITIONS.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 19:10:16 +01:00
Niels Lohmann b18b6fc7e6 Build the parser's syntax error prefix with one concat() (#6013)
Since #6004 made the "while parsing" part unconditional, the three appends
at the start of exception_message() are one fixed string around the
context. Review follow-up to #6004.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 18:27:08 +01:00
Niels Lohmann 6d5581c4e8 CBOR/MessagePack readers: leave one-element arrays to the general path (#6008)
enter_cbor_array and enter_msgpack_array called the out-of-line scalar
run for every non-empty array. When the array's element is an object or
an array, as on every level of [[...]] or the single ring of a GeoJSON
polygon, the call reads nothing; it made 1,000 arrays nested in each
other cost 4 % more instructions (GCC 13) and up to 8 % more time (Apple
clang) than without the run. #5975 had fixed that with an inline
pre-check, which was later dropped after measuring canada only.

The run is now entered only for arrays of two or more elements: the same
comparison as before, so no other row changes. Arrays of one scalar,
which the run read faster, now take the general path; they are rare in
documents (one in citm_catalog, none in twitter or canada). The new
benchmark FromBinaryShape/singles measures them, next to
FromBinaryShape/nested.

Instructions per repetition, new/old, GCC 13 callgrind: nested arrays
0.973 (CBOR) and 0.971 (MessagePack), arrays of one scalar 1.037 and
1.021, every other row within 0.15 %.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 18:25:44 +01:00
Niels LohmannandClaude 590b622d48 parse(): propagate std::bad_alloc instead of crashing on a half-constructed member (#5991)
* Create the DOM parser's member value before placing it (#5985)

json_sax_dom_parser::set_member() constructed the new value in place over
the null member. basic_json(value_t) sets the type before the json_value
allocates, so a std::bad_alloc left a member typed object/array with a
null pointer, and the destructor crashed instead of propagating the
exception. Construct the value first and move it over the member (the
move constructor is noexcept).

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

* Fix CI for the parse() bad_alloc sweep test (#5985)

- sweep_allocator: provide max_size(), construct() and destroy(), which
  GCC 4.8's std::map calls on the allocator directly.
- Declare the non-throwing test lambdas noexcept (-Werror=noexcept on
  recent GCC).
- Give the sax_parse lambda an explicit return type; Clang 3.4 crashes on
  the deduced one in C++11 mode.
- Skip the parser callback sweep with iterator debugging (MSVC debug
  builds, clang-cl), where containers allocate debug proxies inside
  noexcept move constructors and terminate instead of throwing, as in the
  other allocator tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

* Construct a scalar member in place; only a throwing value goes through a temporary

Creating the value first and moving it over the member is needed only when
creating it can throw (a string, a binary value or a container). A scalar
or null is again constructed in place, without the extra move and destroy
per member (and, with JSON_DIAGNOSTICS, without the extra set_parents()).

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

* Spell the nothrow trait without && and fix the construct_member comments

The dispatch in set_member tests std::is_nothrow_constructible, not
whether the value is a scalar. Say so in the comments, and drop the &&
from the trait argument (equivalent for a forwarding reference) so that
astyle no longer inserts spaces around the template brackets.

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

* Say "for example" in the construct_member comments

The overloads are selected by std::is_nothrow_constructible, not by the
kind of value: a custom type that cannot throw takes the first one.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 18:25:30 +01:00
Niels Lohmann 100f676b3e Restore the two commits of #6005 that the stack merge dropped (fixes the build of develop) (#6012)
* basic_json, iterators, serializer: remove checks that invariants make dead

Branch coverage of the test suite and of 24k mutated inputs showed
these conditions as never taken; each is implied by the code around it:

- copy_object_level(): `src_it != src_object.cend()`; dst was built from
  exactly src_object.size() unique keys and src_it advances at most once
  per member
- the general comparison operators (equal_general, less_general,
  three_way_general): the five same-type scalar cases, which the inline
  fast path of every operator handles before calling them (now an
  assert); and the NaN half of compares_unordered() in the mixed-type
  branch, reached only after all six number pairs returned, where only
  a discarded operand is unordered
- serializer, ensure_ascii: the reset of `bytes` under error_handler_t::keep
  and the surrogate-pair escape in the UTF8_ACCEPT case; every
  well-formed multi-byte character is escaped by write_u_escapes() before
  decode() sees it, so decode() only ever accepts DEL here, a single byte
  of which nothing was buffered (now asserts)
- iter_impl(pointer): the if/else chain assigned value-initialized
  iterators to the value-initialized m_it

No change in behaviour: a build that aborts on each removed side passes
the test suite, the fuzz corpora and 23.2M dumps of all 1-, 2- and
boundary 4-byte strings in both ensure_ascii modes.

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

* iter_impl: keep the type-dependent initialization in the constructor

The check is not needed for correctness (m_it is value-initialized), but
without it GCC 13 generates slower iteration loops: a recursive walk over
a parsed document takes 0.5-2.7 % longer (callgrind: +1.9 % instructions
on twitter.json, +0.95 % on canada.json). Clang generates identical code
either way. See the measurements in #6005.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 18:23:44 +01:00
dependabot[bot] bd067fd08c Bump mkdocs-git-revision-date-localized-plugin in /docs/mkdocs (#6011)
Bumps [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin) from 1.6.0 to 1.6.2.
- [Release notes](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/releases)
- [Commits](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/compare/v1.6.0...v1.6.2)

---
updated-dependencies:
- dependency-name: mkdocs-git-revision-date-localized-plugin
  dependency-version: 1.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-11-02 17:57:02 +01:00
Niels Lohmann 3354436ec4 json_view: remove checks that invariants make dead (#6006)
Branch coverage of the test suite and of 24k mutated inputs showed
these conditions as never taken; each is implied by the code around it:

- view_serializer::write_codepoint<EnsureAscii>(): the only caller
  passes the byte a run of plain output stopped at (a quote, a
  backslash or a control character), so the function is now
  write_escaped(), which writes that byte's escape sequence
- load_image(): `owned_image.empty() || image != owned_image.data()`;
  both callers hand in a fresh document_data, and for load(vector&&)
  the image is owned_image itself
- set_moved(): reserve_moved(); all three callers reserved first or
  have the moved flag set (the documented precondition)
- view_side::string() and json_side::string() in equal(): only used
  after both sides were found to be strings, so they read the string
  directly (and are noexcept)
- number<false>(): the '1'..'9' test after a sign-less dispatch, which
  only happens for a digit
- value_range(): the pre-loop `is_new || off >= size` test, which the
  loop's first pass repeats on the same node

No change in behaviour: a build that aborts on each removed side passes
the test suite and the fuzz corpora.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 17:54:40 +01:00
Niels Lohmann 596028c460 Drop the null_result parameter JSON_IMPLEMENT_OPERATOR no longer uses (#6005)
Without the same-type scalar cases, the macro body has no use for it, and
JSON_IMPLEMENT_SCALAR_CASES is now used only by JSON_IMPLEMENT_SCALAR_FAST.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 17:54:39 +01:00
Niels Lohmann 5c4f585ac2 Lexer, parser, stream adapter, SAX: remove checks that invariants make dead (#6004)
Branch coverage of the test suite and of 24k mutated inputs showed
these conditions as never taken; each is implied by the code around it:

- lexer: `next_unget` in get_codepoint_bulk() and scan_literal_bulk().
  unget() is only called at the end of scan_number(), in scan_comment()
  and in skip_bom(); every token scan starts with a plain get() in
  skip_whitespace() that consumes a pending unget, and nothing between
  that get() and the bulk helpers ungets (now asserts, as in
  get_after_string_run())
- lexer: `number_type == value_integer` in convert_integer(): both
  callers exclude value_float and the type has three values
- parser: `!context.empty()` in exception_message(): all callers pass a
  literal
- input_stream_adapter: `refill` in get_character_slow(): the function
  is only called after get_character() found the get area exhausted,
  and the variable recomputed that comparison
- json_sax_dom_callback_parser: `ref_stack.back()` in key() (the null
  case returned a few lines earlier, and the callback in between cannot
  reach ref_stack), `is_structured()` in end_object() (non-null entries
  are only pushed for objects and arrays), `!key_stack.empty()` in
  current_key() (a kept object pushed its key before any value)

No change in behaviour: a build that aborts on each removed side passes
the test suite, the fuzz corpora and 40k random documents through every
input adapter in four macro configurations.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 17:54:39 +01:00
Niels LohmannandClaude Opus 5.5 1d69ef9ab4 Raise line coverage to 99.9 %: fix the measurement, remove unreachable code, add tests (#5997)
* CI: measure line coverage without lcov's unexecuted-block adjustment

Drop geninfo_unexecuted_blocks=1 from the lcov capture of ci_test_coverage:
it reset every line of an inlined or templated function to 0 as soon as one
copy had an unexecuted block, which understated the line coverage by about
three points.

Add -fvar-tracking-assignments to both coverage builds. At -O0, GCC inlines
always_inline functions before it places the coverage counters, so the call
sites of such helpers (put_literal() and others) got no line record and
showed as 0 in an -O3 translation unit that never reaches them. With the
flag, the call sites carry counts in every translation unit. The generated
code is identical.

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

* Remove unreachable code found by the coverage analysis

Remove code that no input can reach, and mark the lines that cannot be
covered with LCOV_EXCL_LINE:

- BJData writer: the dry_run parameter of the ND-array element writers was
  always true; replace them by range checks.
- BON8 writer: call throw_integer_out_of_range() directly instead of
  write_bon8_value() for values that always throw.
- binary_writer: integer_bits() is only called for integers of up to 64 bits.
- serializer, view serializer, lexer: replace guards that the callers make
  unreachable by assertions or by the simpler code (surrogate pairs under
  ensure_ascii, next_unget, '-' at the end of the buffer).
- json_view: drop unreachable branches in scalar(), set(), check_utf8_scan(),
  append_input_impl() and unescape().
- Mark exception-cleanup braces, 2 GiB limits, big-endian and 32-bit code, and
  fall-through case labels with LCOV_EXCL_LINE.

No behavior changes for any input that reaches these functions.

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

* Tests: cover the remaining lines of the library headers

Add tests for the lines of include/nlohmann that were not covered: the
binary readers and writers, the lexer and locale paths, the json_view
modules, the custom number, key and array types, json_pointer, json_patch,
diff and the iterators.

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

* Fix test failures in the coverage tests

- unit-custom-object-key-type: remove the unused make_strict_key(strict_key)
  overload, the unused range constructor and default constructor, and guard
  data() with JSON_DIAGNOSTICS (unused-function/-member-function errors with
  GCC and clang -Weverything).
- unit-json_view_compare: move the two new sections to the new
  unit-json_view_compare_values.cpp, as the object file got too large for the
  MinGW assembler again, and use a std::map with std::greater instead of
  std::unordered_map, which does not accept the incomplete basic_json
  (clang 3.9, icpc).
- unit-json_view_dump: rename the variables that hid outer ones (MSVC C4456).
- unit-stream-bulk-scan: restore the real size of the oversized get area
  before the adapter is destroyed (JSON_PRECISE_STREAM_POSITION reads the
  character at the read position), and skip the test where the streambuf
  cannot hold a get area larger than an int (MSVC).
- unit-regression1: with JSON_NO_THREAD_LOCAL, copies are built member by
  member and keep correct timestamps, so check the corresponding outcome.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

* Return std::size_t from the hash helper in the ordered_json test

MSVC (Win32) rejected the implicit conversion of the unsigned long long
product to the 32-bit std::size_t (C4244 as an error). Also note when
JSON_NO_THREAD_LOCAL is set in the regression test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 17:54:38 +01:00
Niels Lohmann ff0bdfdef3 Keep the byte range in exceptions about the root value (#5990)
* Keep the byte range in exceptions about the root value (#5987)

With JSON_DIAGNOSTICS and JSON_DIAGNOSTIC_POSITIONS both set, exception::diagnostics()
and the json_view diagnostics() returned early for a value without a path (the
root), dropping "(bytes a-b)". Build the "(path) " prefix only when there are
tokens and always append the byte range.

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

* Guard the null value of a value-initialized iterator; drop the unneeded found flag

With the root's byte range, diagnostics() reaches get_byte_positions() also
with JSON_DIAGNOSTICS when there is no value, as for a value-initialized
iterator (invalid_iterator.212). get_byte_positions() now returns no range
for a null value, the same change as #6003, so either can be merged first.

In the view, a value that value_path() does not find leaves no tokens, so the
found flag added nothing to the tokens.empty() test.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-02 17:50:40 +01:00
dependabot[bot] 7328310136 Bump mkdocs-material from 9.7.7 to 9.8.0 in /docs/mkdocs (#6010)
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.7.7 to 9.8.0.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.7.7...9.8.0)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-11-02 17:48:55 +01:00
Niels LohmannandClaude Opus 5.5 bfe69c73c2 json_view: get<T>() of a boolean throws for the exact number types, as basic_json does (#5992)
* json_view: get<T>() of a boolean throws for number_integer_t, number_unsigned_t and number_float_t like basic_json (#5988)

basic_json::get<T>() of a boolean throws type_error.302 for exactly
number_integer_t, number_unsigned_t and number_float_t (dedicated from_json()
overloads) and gives 0/1 for every other arithmetic type. The view returned
0/1 for all of them, contradicting its documentation. The view now throws
the same exception (same message, with path/bytes decoration) for these three
types. basic_json is unchanged; its behavior is documented and pinned by a test.

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

* tests: skip throwing json_view bool get<T>() combinations without exceptions (#5988)

check_boolean_get_parity() called get<T>() for number_integer_t,
number_unsigned_t and number_float_t in its JSON_NOEXCEPTION branch, but a
boolean throws type_error.302 for exactly these types, so JSON_THROW aborted
test-json_view_cpp11/cpp17 in ci_test_noexceptions. Skip these combinations
there; the throwing checks stay in the exceptions-enabled build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

* Expect the byte range of the root in the json_view boolean get<T>() test

With JSON_DIAGNOSTIC_POSITIONS, the type_error.302 message starts with
"(bytes 0-4)"; build the expected text with json_view_test::message(),
as the other tests of the root value do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 17:48:43 +01:00
Niels LohmannandClaude 494a74c242 insert(): strong guarantee for single elements, basic guarantee for the rest (#5996)
* Make basic_json::insert() provide its documented strong exception guarantee (#5986)

A failed allocation while the new elements were copied left the value
changed, and with JSON_DIAGNOSTICS stale parent pointers behind. The
extra work now happens almost only on the failure path:

- Array insert(pos, cnt, val) and insert(pos, first, last) append the
  copies at the end and rotate them into place. If a copy throws, the
  appended elements are erased again (noexcept) and the parents are set.
  Moving a basic_json cannot throw, so reallocation is safe. This is no
  slower than vector::insert (faster for numbers), needs no temporary
  array, and keeps the elements that libstdc++ lost on reallocation.
- Array insert(pos, val) copies a non-scalar value first and inserts it
  by move, except at the end, where vector::insert is strong. Scalars
  keep the direct path.
- The object range insert(first, last) into an empty object uses the
  container's own range insertion and clears the object on an exception.
  Into a non-empty object it inserts member by member and logs one bit
  per source member (a new member is detected by the size change; no
  allocation for the first 256 members); on an exception the members
  added are erased by walking the source range. No assumption that
  key_type is string_t.
- The parents are set when a failed insertion is undone.

The regression test fails every allocation of every insert() overload in
turn, for json and ordered_json, and checks the value and its parents.

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

* Fix clang-tidy and -Wnrvo findings in insert rollback helpers

Declare the rollback helpers non-movable, replace the nested conditional
and C array in object_insert_rollback, silence the intentional copy in the
allocator test, and avoid the missed NRVO in the test factory lambda.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

* insert(): strong guarantee for single elements, basic for the rest

Rework of the previous two commits, following the discussion in #5996:
the standard containers give the strong guarantee only for a single
element (std::vector: at the end, or if the exception does not come from
copying T; std::map: single-element insert), and copying a basic_json
allocates. Rebuilding a rollback for the count, range and object-range
overloads on top of array_t/object_t made the code verbose and slower.

- insert(pos, const basic_json&): at end() forward as before (the
  standard covers it); elsewhere copy first and insert by move, as
  libstdc++ does internally (libc++ shifts the tail before copying).
- insert_iterator() and object insert(first, last) set the parents in a
  scope guard, so a failed insertion leaves a valid value with
  JSON_DIAGNOSTICS too (the next assert_invariant() aborted before).
- Docs: strong guarantee for (1), basic guarantee for (2)-(5); the
  argument checks throw before anything is changed.
- Test: allocation-failure sweep checks the strong guarantee for (1) and
  validity, type and parents for the other overloads.

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

* insert(): document the exception safety of overloads 2 to 5 once

The four basic-guarantee statements were identical up to array/object.

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

* insert(): simplify the wording of the basic guarantee

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 17:48:29 +01:00
Niels LohmannandClaude Opus 5.5 bdc737db6d json_view: dump() without StringType::capacity() (#5999)
* json_view: dump() without StringType::capacity() (#5994)

output_buffer::grow() compared the output size with m_out.capacity(),
which the StringType requirements do not include, so dump() did not
compile with the tests' alt_string. Keep what was last reserved in the
buffer itself and use it as a lower bound of the capacity instead.

Add json_view tests with alt_string (read-only and editable documents,
dump with several growth steps, save/load), and document reserve(n) and
resize(n) as the StringType requirements of basic_json_view::dump.

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

* Use a raw string literal in the alt-string json_view test

clang-tidy (modernize-raw-string-literal) rejects the escaped literal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 17:48:16 +01:00
Niels LohmannandClaude 66e2eeeec0 Do not construct the base class when destroying a container (#6000)
* Do not construct the base class when destroying a container (#5995)

json_value::destroy_container() and destroy_walk() used default-
constructed basic_json values as stand-ins, which construct a
CustomBaseClass that belongs to no value. A base class whose default
constructor allocates made the noexcept destructor allocate again, and
terminate if that allocation failed, which #5762 set out to prevent.

Use data (type and value, no base class) as the stand-in instead, and
pass the children's m_data to the walk helpers.

Add a test with a counting base class: destroying a value constructs no
base object and destroys exactly one per value, also for values nested
deeper than the recursion depth limit.

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

* Release the test value with = nullptr instead of reset()

clang-tidy (readability-ambiguous-smartptr-reset-call) rejects j.reset()
because the pointee inherits a reset() from counting_base.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

* Use std::swap for the container stand-in in destroy_container

The unqualified call after `using std::swap` would let a user-provided
swap(json_value&, json_value&) intercept the destruction path. Call
std::swap directly.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 17:48:03 +01:00
Niels LohmannandClaude Opus 5.5 03d408aafa JSON_DIAGNOSTIC_POSITIONS: comparing a value-initialized iterator throws instead of crashing (#6003)
* JSON_DIAGNOSTIC_POSITIONS: comparing a value-initialized iterator throws instead of crashing

With JSON_DIAGNOSTIC_POSITIONS, comparing a value-initialized iterator
(which has no container) with another iterator built the
invalid_iterator.212 message from the byte positions of the iterator's
value, which is a null pointer: UBSan reports "member call on null
pointer" in exception::get_byte_positions(), then the process crashes.
Every other configuration throws invalid_iterator.212.

get_byte_positions() now returns no positions for a null value, as the
JSON_DIAGNOSTICS path already does.

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

* Declare the value-initialized iterator in the test const

clang-tidy (misc-const-correctness) flags it, as it is only compared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 17:47:48 +01:00
Niels LohmannandClaude Opus 5.5 76dbe8f9c9 Fix the red CI on develop: Visual Studio 2017 build of the BSON writer, Valgrind timeouts (#6009)
* CI: give the Valgrind tests a timeout of one hour

Under Valgrind, test-json_view_builder_cpp11 and test-ordered_json_cpp11
took 1435 s and 1390 s on develop (ddc34f5), close to ctest's default
timeout of 1500 s. On the next run (b2674a4) the whole job was about 10 %
slower and both timed out, failing ci_test_valgrind on develop and on
every PR based on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

* BSON writer: drop the SFINAE guard that Visual Studio 2017 cannot deduce

write_bson_document_single_pass() was a member template enabled by
is_detected<sink_written_t, SinkType>. MSVC 19.16 (Visual Studio 2017)
fails to deduce it through the class-scope alias template (C2672, C2783)
when it compiles to_bson() and to_bon8(), so every Visual Studio 2017
job on AppVeyor fails since #5979.

The guard is not needed: as a non-template member of the class template,
the function is only instantiated when called, and its only caller is
the write_bson_document() overload for sinks that have written(), which
already calls oa.written() and oa.rewind() itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>

---------

Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 17:47:21 +01:00
Niels Lohmann b2674a4a2f BSON reader: check array element names in place in strict mode (#5984) 2026-11-01 21:03:35 +01:00
Niels Lohmann e2423a1857 CI: pin ubuntu-latest jobs to ubuntu-26.04 (#5983)
GitHub is moving the ubuntu-latest label from Ubuntu 24.04 to 26.04
between October 19 and November 19, 2026 (actions/runner-images#14748).
Pin every ubuntu-latest job to ubuntu-26.04 so the switch does not
change the toolchain under our jobs, and so the behaviour does not
depend on when GitHub reaches our runs.

Jobs pinned to ubuntu-24.04 and ubuntu-24.04-arm are unchanged.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 20:43:07 +01:00
Niels Lohmann 67b103e506 Fix clang-tidy errors in json_view tests on develop (#5989)
readability-math-missing-parentheses in unit-json_view_builder.cpp (#5974)
and performance-inefficient-string-concatenation in
unit-json_view_positions.cpp.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 20:42:58 +01:00
Niels Lohmann ddc34f546a json_view: exceptions name the path and the bytes of the value (#5974)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:25:26 +01:00
Niels Lohmann f022e3c59c Binary readers and writers: faster UTF-8 checks of strings (#5982)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:23:27 +01:00
Niels Lohmann 9742edc294 BSON writer: write to_bson(j) in one pass, with sizes written afterwards (#5979)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:23:12 +01:00
Niels Lohmann 517444b504 accept() checks strings without copying them (#5978)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:22:58 +01:00
Niels Lohmann fb515ddc34 UBJSON/BJData readers: read optimized arrays of numbers in one loop (#5981)
* UBJSON/BJData readers: read optimized arrays of numbers in one loop

An array with a type marker for a fixed-size number ($U, $i, $I, $l, $L,
$d, $D, and BJData's $u, $m, $M), including the data of a BJData ndarray,
gives its elements no markers. When the input is contiguous, read the
elements that are in the input in one loop - load, byte swap for the
format's byte order, emit - instead of one trip through
parse_ubjson_internal and get_ubjson_value per element. Elements the
input ends before, other types, and non-contiguous inputs are read as
before.

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

* UBJSON/BJData tests: assign the parsed value instead of casting it to void

GCC reports -Werror=unused-result for static_cast<void>(json::from_ubjson(...))
and json::from_bjdata(...): a cast to void does not silence warn_unused_result
on GCC. Assign to a json, as the other tests do.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:22:33 +01:00
Niels Lohmann edf8d17601 MessagePack reader: read runs of scalar array elements in one loop (#5980)
* MessagePack reader: read runs of scalar array elements in one loop

As for CBOR: when an array opens and the input is contiguous, read the
integers, floats, booleans, and nils that follow in a tight loop instead
of going through parse_msgpack_internal and parse_msgpack_value for every
element. The loop stops at any other kind of value and when fewer than 9
bytes are left; those values are read by the general path as before.
Non-contiguous inputs are not affected.

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

* MessagePack reader: enter the scalar run only when a scalar follows

As for CBOR: enter_msgpack_array tests the first byte and the remaining length
inline and calls the out-of-line run only for a scalar, so arrays of maps or
strings no longer pay for a call that reads nothing; the run's loop condition
moves to the end (do-while).

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

* MessagePack reader: mark the initial accepted in the scalar run as a false-positive dead store

ci_infer reports DEAD_STORE for 'bool accepted = true;' in the MessagePack
scalar run, as in the CBOR one, because every case assigns accepted before it
is read.

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

* MessagePack tests: assign the parsed value instead of casting it to void

GCC (ci_test_gcc) reports -Werror=unused-result for
static_cast<void>(json::from_msgpack(...)): a cast to void does not silence
warn_unused_result on GCC. Assign to a json, as the other tests in the file do.

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

* MessagePack reader: drop the scalar pre-check before the run

enter_msgpack_array now calls the run directly, and parse_msgpack_scalar_run
tests the remaining count and length at the top of a while loop instead of
relying on msgpack_scalar_follows(); its own switch already leaves on any
value that is not a scalar.

Instructions per repetition, new/old: SAX canada 0.946 (clang) and 0.973
(GCC 13), DOM read canada 0.991 / 0.992; no row more than 0.3 % higher.

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

* MessagePack reader: say why the initial accepted in the scalar run stays

As for CBOR: Infer's DEAD_STORE report is right, not a false positive. The
initializer is kept for clang-tidy's cppcoreguidelines-init-variables.

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

* MessagePack reader: give the scalar run the bulk tag instead of a wrapper

As for CBOR: parse_msgpack_scalar_run takes the bulk-scan tag itself and is
the function kept out of line, so parse_msgpack_array_start goes.

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

* MessagePack reader: start the scalar run's accepted at false

As for CBOR: Infer ignores dead stores of 0, so the suppression goes.

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

* MessagePack reader: let the scalar run find its array itself

As for CBOR: parse_msgpack_scalar_run reads container_stack.back() in its
bulk version, so the caller no longer evaluates it for input that is not
contiguous.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:22:32 +01:00
Niels Lohmann aecbef3949 Binary readers: swap the bytes of floats with a single byteswap (#5976)
* Binary readers: swap the bytes of floats with a single byteswap

byte_swap reversed float and double values byte by byte. GCC does not
merge that loop into one bswap, and C++23's std::byteswap accepts only
integers. Overloads for float and double now copy the bits into a
uint32_t/uint64_t, call detail::byteswap, and copy them back. This
applies to every binary reader that uses get_number.

In the CBOR reader, the single- and double-precision float cases call a
non-inlined helper. Without it, GCC stopped inlining the stream
adapter's get_character() into parse_cbor_internal, which made reading
from a std::istream about 0.5 % slower.

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

* CBOR reader: inline get_cbor_float() and always inline get() instead

The never-inlined get_cbor_float() costs a call for every float read
from input without bulk access: reading canada.json from CBOR through a
FILE* became 5.6 % slower on Apple clang in the benchmark suite. The
helper existed only because GCC 13 stopped inlining the stream adapter's
get_character() into parse_cbor_internal. Always inlining
binary_reader::get() fixes that as well.

callgrind, all binary formats on buffer, std::istringstream and FILE*
input (canada and citm_catalog): GCC 13 0.986-1.003, GCC 16 0.994-1.006,
Clang 23 identical. Apple clang suite: FromBinaryFile/cbor/canada 0.939,
geomean of the 53 binary reader rows 0.998.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:22:32 +01:00
Niels Lohmann 6c3ab966d3 CBOR reader: read runs of scalar array elements in one loop (#5975)
* CBOR reader: read runs of scalar array elements in one loop

When a definite-length CBOR array opens and the input is contiguous, read
the integers, floats, booleans, and nulls that follow in a tight loop
instead of going through parse_cbor_internal's container logic and
parse_cbor_value's dispatch for every element. The loop stops at any other
kind of value and when fewer than 9 bytes are left; those values are read
by the general path exactly as before. Non-contiguous inputs are not
affected (tag dispatch on the bulk-scan capability).

Also pass a member empty string as the number source to number_float
instead of constructing a std::string for every float.

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

* CBOR reader: address review of the scalar-run reader

- parse_cbor_scalar_run: set the size explicitly in every case that
  reads a value, instead of relying on a default that every other case
  overwrites.
- Remove cbor_scalar_follows(): parse_cbor_scalar_run already returns on
  the same conditions, and without the pre-check SAX canada needs another
  8.5 % fewer instructions with GCC 13 (0.915 against the previous
  version), with no row more than 0.5 % worse (Mac and GCC).
- Restore the comment on why parse_cbor_internal copies the container
  frame.

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

* CBOR reader: enter the scalar run only when a scalar follows

An array of containers or strings called the out-of-line run start once per
array only to leave it at once; on nested data (arrays of objects) that call
made reading slower than before the run reader. enter_cbor_array now tests the
first byte and the remaining length inline and calls the run only for a
scalar, so the run's loop condition moves to the end (do-while).

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

* CBOR reader: mark the initial accepted in the scalar run as a false-positive dead store

ci_infer reports DEAD_STORE for 'bool accepted = true;' in
parse_cbor_scalar_run because every case assigns accepted before it is read.

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

* CBOR reader: drop the scalar pre-check before the run

enter_cbor_array calls the run directly again, and parse_cbor_scalar_run
tests the remaining count and length at the top of a while loop; its own
switch already leaves on any value that is not a scalar. The MessagePack
reader is built the same way.

Instructions per repetition, new/old: clang SAX canada 0.983, read canada
0.993; GCC 13 read canada 0.997, the other rows at most 1.004.

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

* CBOR reader: say why the initial accepted in the scalar run stays

Infer's DEAD_STORE report is right, not a false positive: every case that
reaches the read assigns accepted. The initializer is kept for clang-tidy's
cppcoreguidelines-init-variables.

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

* CBOR reader: give the scalar run the bulk tag instead of a wrapper

parse_cbor_scalar_run takes the bulk-scan tag itself and is the function that
is kept out of line, so the one-line parse_cbor_array_start wrapper goes, as
the UBJSON typed run already does.

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

* CBOR reader: start the scalar run's accepted at false

Infer ignores dead stores of 0 (--liveness-ignored-constant defaults to "0"),
and false is 0 to it, so the suppression and its comment go.

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

* CBOR reader: let the scalar run find its array itself

parse_cbor_scalar_run reads container_stack.back() in its bulk version, so
the caller no longer evaluates it for input that is not contiguous.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:22:31 +01:00
Niels Lohmann 5337d841d4 Document and test the lifetime of string_view members decoded from a json_view (#5973)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:21:31 +01:00
Niels Lohmann 162eda2574 json_view: skip the digits of a fraction 16 bytes at a time (SSE2) (#5971)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:21:19 +01:00
Niels Lohmann 1a018577cc json_view: accept() checks the text without writing an index (#5970)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:21:06 +01:00
Niels Lohmann 76001c6b4c BSON reader: find C-string terminators 8 bytes at a time, skip array element names (#5968)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:20:54 +01:00
Niels Lohmann ec6986c918 Add natvis visualizers for json_document and json_view (#5967)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:20:41 +01:00
Niels Lohmann 3fd3e0fdaa json_view: dump and read canada.json-style floats faster (batched float decisions) (#5908)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-01 17:20:29 +01:00
Niels Lohmann 9c349b1d7c Write integers of 17 to 20 digits eight digits at a time in dump() (#5964)
#5634 made dump() write integers below 10^16 eight digits at a time; larger
ones still took the two-digits-per-division loop and count_digits(). Random
64-bit integers almost all have 17 to 20 digits (99.9 % of signed_ints.json
and unsigned_ints.json), so Dump/signed_ints and Dump/unsigned_ints gained
only 1.4x over 3.12.0, against 2.3x for small integers.

A 64-bit magnitude is now written as its first one to four digits and two
groups of eight. Wider magnitudes (__int128 and class types, #5805) keep the
loop: number types of at most 64 bits are selected by type, so no comparison
is reported as always true; for others the value is compared. The sign
handling of #1447/#5815 (remove_sign() into number_magnitude_t) is unchanged.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-31 13:54:45 +01:00
Niels Lohmann 367963f6bb Test escaped object keys decoded through NLOHMANN_DEFINE_TYPE from a json_view (#5972)
A json_view or json_document decodes a macro-defined struct directly and looks
the members up by their decoded keys. Only plain keys were covered so far.

The new section decodes structs defined with NLOHMANN_DEFINE_TYPE_INTRUSIVE,
..._WITH_DEFAULT and ..._WITH_NAMES from documents whose keys contain escape
sequences, and compares the result with the conversion of the materialized
value. It also pins the difference for a duplicate key written once plain and
once escaped (the view takes the first member, the materialized value keeps
the last one), and that an escaped backslash is part of the decoded key.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-31 13:54:20 +01:00
Niels Lohmann 4fe670b5f4 json_view: decode chains of unicode escapes in a loop (#5969)
After the first \uXXXX escape of a string, slow_string() now decodes the
escapes that follow it directly, while the next six bytes are \u and four hex
digits that are not a surrogate, instead of going round its main loop for each
of them (that is how Python's json.dumps writes non-ASCII text by default).
A surrogate, a bad digit, or fewer than six bytes leave the position at the
backslash: the main loop handles them as before and reports the same error at
the same position.

twitterescaped.json (simdjson-data, 549 KB, 33,036 escapes), json_document::parse(),
A/B in one binary, 6 code layouts, time after / before:

- Apple M1 Max, Apple clang 21: 0.897
- x86-64 Haswell, GCC 16.2: 0.907
- x86-64 Haswell, Clang 23: 0.910

The other files of the benchmark set (twitter, citm_catalog, canada, gsoc-2018,
apache_builds, instruments, tree-pretty, github_events, random, update-center,
semanticscholar-corpus, twitter_timeline) stay within the noise of each machine.

New test: chains of every length from 1 to 40 of escapes that give one, two,
and three bytes of UTF-8, followed by the end of the string, text, escapes,
surrogates, bad digits, and cut in every place, in keys and in values, against
json::parse().

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-31 13:54:02 +01:00
Niels Lohmann 755bb16d7a Fix the red CI on develop: remove the duplicate is_editable in basic_json_view (#5966)
#5919 replaced the bool template parameter Editable of basic_json_view by
view_mode Mode and defined is_editable from Mode. #5890 was written before
that and added a second is_editable = Editable to the private section, which
no longer compiles ("duplicate member", "undeclared identifier Editable"). It
broke every job that builds the json_view tests (macOS, MSVC, clang-cl,
clang on Windows, the C++20 module job, CodeQL).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-30 16:48:31 +01:00
Niels Lohmann d20c4dcd89 json_view benchmarks: compare fairly and state what each row means (#5914)
- bench_view: add "(editable)" rows for json_editable_document and a
  parse+dump workload, so the cost of lazy float conversion shows next to the
  parse row (the traverse workload already includes the parse). Check that
  all engines' dumps agree where outputs are comparable.
- compare.py: add --aligned, which also builds and runs with aligned code and
  reports both tables, so code-layout artifacts become visible. Off by
  default; the default output is unchanged. Not run end to end yet.
- README: say which engines are like-for-like peers (yyjson, simdjson DOM) and
  which are mutable reference points (Boost.JSON, json::parse, the editable
  json_view); explain the lazy float conversion and the eager prototype that
  was measured and dropped.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-30 15:20:12 +01:00
Niels Lohmann ea03d601af json_view: comparison without temporaries and a faster image float check (#5890)
* Compare json_view values without a vector per container and a basic_json per number

operator== of views (view/view, view/json, and editable documents) built two
vectors of members for every object it entered, sorted them with stable_sort
for every object, and converted each number to a basic_json value. It now:

- keeps the members of all open objects in one vector (reserved with
  geometric growth, so that nested objects do not reallocate), and orders
  them by insertion sort for up to 16 members, or not at all when the keys
  ascend already;
- compares numbers of one type directly, and builds a basic_json only for
  numbers of different types;
- compares short texts (keys, numbers, most strings) with two overlapping
  loads (bytes_equal(), in node.hpp);
- first walks both documents in lockstep, in the order of their text, which
  finds most pairs of equal values without the work of the comparison. The
  walk only enters an object if the comparison would visit its members in the
  same order (the object type keeps the order, the keys ascend, or all values
  are scalars), so a difference is never found later than before, and it
  records the containers it found different, so that the comparison does not
  walk them again;
- rejects values of different types and arrays of different sizes before any
  of this, and, for an object type that keeps the order, objects whose first
  (up to four) members have different keys, which ends a comparison that
  differs near the start without preparing the members.

Results are unchanged: numbers compare by value across types, duplicate keys
resolve as parse() resolves them, and objects compare in document order for
ordered_json and by key otherwise.

Instructions of one comparison of a document with an equal copy, macOS arm64
(develop -> now), json_document / ordered_json_document / editable:

  twitter    16.1M -> 7.0M   17.7M -> 1.5M    16.6M -> 7.3M
  citm       45.0M -> 3.4M   47.0M -> 3.2M    45.7M -> 4.3M
  canada    111.4M -> 13.7M  111.4M -> 13.7M  113.3M -> 15.0M
  jeopardy   26.2M -> 3.7M   27.3M -> 3.7M    26.6M -> 12.1M

and of a view with a basic_json value:

  twitter    11.4M -> 5.9M   11.2M -> 7.3M    11.6M -> 5.9M
  citm       33.9M -> 9.7M   32.6M -> 9.1M    34.6M -> 9.8M
  canada     92.9M -> 32.1M  92.9M -> 32.1M   93.9M -> 32.8M

and Linux instruction counts (GCC 13 / Clang 18) of the same comparisons:

  document with an equal copy   json_document     ordered_json_document   editable
    twitter                     -49 % / -52 %     -89 % / -89 %           -48 % / -50 %
    citm                        -90 % / -89 %     -91 % / -90 %           -88 % / -87 %
    jeopardy (4,000 questions)  -85 % / -85 %     -86 % / -86 %           -46 % / -49 %
  view with a basic_json value
    twitter                     -41 % / -45 %     -28 % / -35 %           -45 % / -44 %
    citm                        -63 % / -65 %     -63 % / -66 %           -65 % / -64 %
    jeopardy                    -39 % / -43 %     -14 % / -24 %           -44 % / -43 %

A sweep that places one difference at about 2,100 positions of eight
documents (a token at an even spacing, the first and last tokens, the first,
middle and last member of the root removed, one appended, the document
wrapped) in five kinds of comparison (view/view of read-only and of editable
documents, view/json, json_document, editable/view) finds the same results as
before and no placement slower on the Mac (Clang); on Linux no placement is
slower than 3 % (Clang and GCC).

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

* Check the float tokens of a json_document image without a sort and a scan of every character

load(image_check::full) checked every float token of an image by sorting
the token ranges, scanning the token character by character, and comparing
the digit layout with the node's. Now:

- the ranges are sorted only if they are not sorted already (save() writes
  them in the order of the nodes, so they are);
- a token of the shape [-]digits.digits whose digit counts are the ones the
  node records (nearly all of them) is accepted by checking its digits eight
  at a time, without the general scan;
- the general scan skips runs of digits eight at a time.

Damaged tokens are still rejected as before: the check accepts exactly the
tokens that the general scan accepts.

Instructions of load(image_check::full) (develop -> now):

  macOS arm64        canada 44.6M -> 30.9M (-31 %), jeopardy 11.3M -> 10.7M,
                     citm 10.4M -> 10.0M, twitter 5.06M -> 4.94M
  Linux GCC 13       canada -50 %, jeopardy -43 %, twitter -31 %, citm -28 %
  Linux Clang 18     canada -42 %, jeopardy -48 %, twitter -35 %, citm -32 %

image_check::bounds is unchanged (within 0.4 %).

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

* Rename names that Flawfinder takes for the file function open()

The comparison cursors' open() is now enter(), and a test's open and
close strings are head and tail.

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

* Fix the compiler and lint failures of the json_view comparison

- all_digits(): the lambda declares its constant itself; MSVC does not
  let a lambda without captures read a constexpr local of the function
- equal(): the frame's "in document order" index is a namespace-scope
  constant (document_order); the local constexpr npos in the default
  member initializers of the local struct crashed GCC 9 and MinGW GCC
  and was not found by MSVC
- keys_differ_early() keeps the first keys in std::arrays (cpplint:
  variable-length arrays; clang-tidy: C arrays), and the basic_json
  side's first_keys() is not noexcept (key() may throw)
- the numbers of one type are compared in an if chain instead of a
  nested conditional operator
- the dump test avoids C arrays and temporary string concatenations

View comparison instructions are unchanged (Apple clang, twitter, citm,
canada: -0.1 % to +0.1 %).

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

* Keep the byte comparison helpers in compare.hpp

Address review comments: bytes_equal() and bytes_less() move from node.hpp
to compare.hpp, their only user; key_less() no longer splits the comment of
resolve_indices() from its function; and the loop counters of bytes_equal()
and all_digits() are scoped to their loops.

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

* Dispatch on the compile-time conditions of the json_view comparison

MSVC (/W4 /WX) reported C4127 (conditional expression is constant) for
the template parameter EA and the object type's ordering in an if
condition; both are now tag-dispatched.

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

* Remove a nested duplicate guard from the json_view image test

clang-tidy reported the inner #if !defined(JSON_NOEXCEPTION) as
redundant (the test case is in the same #if) and a find() != npos, which
gets the NOLINT the other tests use.

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

* Mark Infer's null dereference in materialize() as a false positive

Infer (ci_infer, also red on develop since #5882) reports a null
dereference in json_sax_dom_parser::null() called from materialize(). The
member pointer the parser stores a value of an object in is set by the
key() before it, so it is not null there.

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

* Move the json_view comparison tests into their own file

With the tests this branch adds, the object file of unit-json_view_dump.cpp
got too large for the MinGW x64 assembler ("file too big"). The test case
"json_view comparison" is now unit-json_view_compare.cpp, unchanged and
also built with C++17.

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

* Build the DOM parser with Visual Studio 2015 again

Since #5882, the three VS 2015 jobs of AppVeyor fail on develop:
- the detection of keys that can be indexed instantiated std::hash for
  every string type, which VS 2015 rejects with a static_assert for a type
  it does not hash (alt_string): std::hash is now looked at only for
  objects in a vector
- the frame stack copied its frames with std::copy to a raw pointer, which
  VS 2015 reports as unsafe (C4996, an error with /WX): a loop now

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

* json_view: no per-object allocations in ordered_json comparisons

For an object type that keeps the order of its members (ordered_json),
resolve_indices() allocated a vector per compared object, and
resolve_members() two. They now use one working vector owned by equal(),
whose capacity is reused, and resolve_indices() needs none when the keys
are unique. resolve_members() sorts small objects by insertion, as the
other paths do.

Instructions per comparison (callgrind, GCC 13 and clang 18, x86-64):
twitter, ordered_json view == ordered_json: 0.939 / 0.941; 20000 small
objects with a duplicate key: 0.741-0.768; all other rows (json,
citm_catalog, canada, view == view) within 0.988-1.003.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-30 15:19:42 +01:00
dependabot[bot] e2cb15c479 Bump the codeql-action group across 1 directory with 4 updates (#5961)
Bumps the codeql-action group with 4 updates in the / directory: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.39.0 to 4.39.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee...9b3254085494b55a0f7c4c2b3d2d52cc712ce370)

Updates `github/codeql-action/autobuild` from 4.39.0 to 4.39.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee...9b3254085494b55a0f7c4c2b3d2d52cc712ce370)

Updates `github/codeql-action/analyze` from 4.39.0 to 4.39.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee...9b3254085494b55a0f7c4c2b3d2d52cc712ce370)

Updates `github/codeql-action/upload-sarif` from 4.39.0 to 4.39.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee...9b3254085494b55a0f7c4c2b3d2d52cc712ce370)

---
updated-dependencies:
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/init
  dependency-version: 4.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-30 15:19:08 +01:00
dependabot[bot] c451fac1bc Bump step-security/harden-runner from 2.22.1 to 2.22.2 (#5962)
Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.22.1 to 2.22.2.
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/ccd8616d44fd3846e67624a50d5aad6d37bf2d25...dc2769abcc0fcfbadfc1df54081c1608579ef6b2)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-30 15:18:56 +01:00
dependabot[bot] 28f71914b5 Bump egor-tensin/setup-mingw (#5963)
Bumps [egor-tensin/setup-mingw](https://github.com/egor-tensin/setup-mingw) from 41b837e47d7f85214629d255b9c4bc3fcbe9fd63 to d54f5ef0ce585bd3fbb1f8a71b5b254f59dbf931.
- [Release notes](https://github.com/egor-tensin/setup-mingw/releases)
- [Changelog](https://github.com/egor-tensin/setup-mingw/blob/master/CHANGELOG.md)
- [Commits](https://github.com/egor-tensin/setup-mingw/compare/41b837e47d7f85214629d255b9c4bc3fcbe9fd63...d54f5ef0ce585bd3fbb1f8a71b5b254f59dbf931)

---
updated-dependencies:
- dependency-name: egor-tensin/setup-mingw
  dependency-version: d54f5ef0ce585bd3fbb1f8a71b5b254f59dbf931
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-30 15:18:44 +01:00
Niels Lohmann 0b91f9ddd8 json_view: check_utf8 skips well-formed runs with the parser's string scan (#5926)
* json_view: check_utf8 skips well-formed runs with the parser's string scan

Strings of 32 bytes or more that are written into an editable document
are validated with scan_string_run(), which skips well-formed UTF-8 16
bytes at a time; the byte-wise check runs only from where the scan found
ill-formed UTF-8, to report the same type_error.316. Shorter strings
keep the byte-wise check (inlined with a constant start, so that this
path is the code it was), where the vector scan costs more than it
saves.

set()/push_back() of strings of 32 bytes or more take 0.29-0.76 of the
time (x86-64 GCC, averaged over code layouts) and 0.25-0.80 (AArch64
clang); shorter strings take 1.5-4 % fewer instructions; the json_view
rows of bench_edit execute at most 0.04 % more instructions.

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

* tests: avoid sign conversion in json_view_edit UTF-8 check

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

* json_view: use while in check_utf8_bytewise

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-30 15:17:55 +01:00
Niels Lohmann 0115bb47b3 Name the source and license of adapted code in the file comments (#5965)
The files with code adapted from fast_float, Zmij and simdjson carried the
authors' SPDX copyright lines, but their file comments did not say what
was taken or under which license: number_parse.hpp, to_chars.hpp,
simd_scan.hpp and view/simd.hpp now do, as zmij.hpp and the yyjson-based
view files already did. README and the license page now also name
fast_float's eight-digit parsing and the lexer's use of simdjson's UTF-8
check. Comments only.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-30 15:17:24 +01:00
Niels Lohmann ea8a05484b Fix implicit-conversion sanitizer failure in unit-class_parser.cpp (#5960)
Constructing a std::string from uint8_t iterators converts values >= 0x80
implicitly to char, which ci_test_clang_sanitizer rejects. Convert each
byte with an explicit static_cast.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-30 09:56:06 +01:00
Niels Lohmann 2aecd86b37 Document the contract of object keys passed to json_sax::key and key callbacks (#5956)
* Document the contract of object keys passed to json_sax::key and key callbacks

Describe what the name passed to json_sax::key and to a parser callback
for parse_event_t::key holds when parsing JSON text: escapes are decoded
to UTF-8, different spellings of a name yield identical strings, the name
is validated before the call (invalid escapes or UTF-8 give a parse error
and no key event), no normalization or case conversion is applied, the
event precedes the ':' check, and duplicate names are reported once per
occurrence. Also note that sax_parse passes binary-format keys unchanged.

See discussion #5955.

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

* Add a test for the object key contract and correct the BON8 note

Pin the guarantees documented for json_sax::key and the key event of
parser callbacks: decoded names, validation before delivery, delivery
before the colon, one event per repeated name, and the binary formats.
BON8 rejects ill-formed UTF-8 in a name even with sax_parse, so the
note no longer lists it with the formats that pass bytes through.

See discussion #5955.

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

* Fix the GCC build of the object key contract test

GCC 11 in C++11 mode rejects a default argument on a lambda parameter
(-Wc++14-extensions) and ignores a static_cast<void> on the
warn_unused_result of parse(). Pass the input format explicitly and bind
the parse result to a variable.

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

* Add version history for the object key contract

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-29 07:37:33 +01:00
Niels Lohmann 5eccbbd2bc Fix clang-tidy misc-redundant-expression in unit-json_view_image.cpp (#5958)
Split the combined has_save/has_load static_asserts so clang-tidy no
longer sees both sides of && as equivalent (develop ci_clang_tidy failure).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-29 07:36:11 +01:00
Niels Lohmann 46bead6e13 Fix the VS2015 build of unit-json_view_positions.cpp (#5957)
VS 2015 does not accept std::string::npos in a constant expression (C2131),
and the constant is only used at run time.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-28 22:08:55 +01:00
Niels Lohmann 54f6b3ef06 json_view: source positions in materialize() with JSON_DIAGNOSTIC_POSITIONS (#5945)
* json_view: source positions in materialize() with JSON_DIAGNOSTIC_POSITIONS

With JSON_DIAGNOSTIC_POSITIONS, materialize() now gives every value the
start_pos()/end_pos() that basic_json::parse() would give it, so exceptions
about materialized values name the same bytes (#5864).

- json_sax_dom_parser takes the lexer type as a defaulted template
  parameter; materialize() passes position_source, which reports the
  positions it derives from the index. diagnostic_positions treats npos as
  "no position" and keeps ranges all-or-nothing.
- Strings with escapes keep the offset of their opening quote plus one in
  `next` (only with the macro); materialize() scans from there to the closing
  quote. The end of an array or object is found by scanning from the end of
  its last element over whitespace, comments and a trailing comma.
- In editable documents, values written by edits, arrays and objects whose
  elements changed, and containers whose last element has no position get
  none. Images keep the flag is_new, and load() checks that `next` of a
  string is within the text.

Nothing changes on the parse path without the macro. The view's own
exceptions still carry no byte range, so the tests that compare them with
those of materialized values skip it under the macro, as they skip the path
under JSON_DIAGNOSTICS.

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

* Indent comment in unit-json_view_from_json.cpp

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

* Address review: clearer position code and docs

- position_source gets clear(); set_scalar() returns early for new values,
  switches on node_kind, and uses no local copies; the one position_source
  per materialize() call is documented
- no npos + 1 for containers without a position; a comment on why the end
  of a container is reported as its closing bracket
- less duplication under #if in materialize() and the builder
- diagnostic_positions sets npos explicitly
- docs: positions of basic_json values after changes, positions in images
  depend on how the document was parsed, when next is set, and the cost of
  positions while parsing

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

* Share the comment scanners of the view builder with materialize()

skip_line_comment() and find_block_comment_end() in scan.hpp are used by
the builder's comment() and by position_source::container_end(), which
had its own copy.

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

* Address review: if/else for container positions, clearer next field

- the opening bracket of a container sets positions with an if/else instead
  of a ternary, and the frame takes its start from positions
- the closing bracket of a container is found in nested if/else; the parent's
  last_end is taken from positions, so it is npos whenever no range is set
- architecture.md: the next field reads "or 0 if it was not; all other
  values: 0" instead of "else 0; otherwise 0"

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

* Fix GCC unused-result and clang-tidy raw-string findings in unit-json_view_positions.cpp

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-28 20:24:49 +01:00
Niels Lohmann 091c10d4a5 Fix self-aliasing in json_pointer::operator/= and patch_inplace (#5936)
* Fix self-aliasing in json_pointer::operator/= and patch_inplace

json_pointer::operator/=(const json_pointer&) passed iterators into its
own token vector to insert() when a pointer was appended to itself
(p /= p), which is undefined behavior; libstdc++ produced "/a/b//" for
"/a/b". The pointer now appends a copy in that case.

basic_json::patch_inplace iterated the patch while changing *this, so
j.patch_inplace(j) read freed memory. It now applies a copy of the
patch when the patch is the value itself. A patch stored inside the
value remains undefined behavior and is documented as such; copying the
patch unconditionally would double the time of a large patch.

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

* Fix JSON_DIAGNOSTICS test crash and clang-tidy hit in patch_inplace self-aliasing

The spare-capacity test reallocated non-empty elements through get_ref(), which leaves stale parent pointers under JSON_DIAGNOSTICS; reserve while the array is empty instead. Suppress performance-unnecessary-copy-initialization for the copy that is needed because *this is modified.

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

* Detect a patch stored inside the patched value with JSON_DIAGNOSTICS

patch_inplace applied a copy only when the patch was the value itself. With JSON_DIAGNOSTICS the parent pointers make it cheap to also detect a patch nested inside the value, so that case is handled the same way. Without diagnostics it stays documented undefined behavior.

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

* Silence misc-const-correctness for patch_aliases_this

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

* Fix clang-tidy findings in the operator/= self-append test

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-28 20:23:55 +01:00
Niels Lohmann 2120927a7a Fix the VS2015 build of unit-json_view_edit_values.cpp (#5947)
MSVC 2015 treats two function templates that differ only in a decltype
return type as a redefinition (C2995), which breaks all three Visual
Studio 2015 jobs on AppVeyor. Overload on the view's mode in the
parameter type instead; template argument deduction ignores the
read-only-to-editable conversion, so each view still selects the
overload of its own mode.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-28 19:46:28 +01:00
Niels Lohmann 282079ba82 Fix clang-tidy findings in unit-json_view_from_json.cpp (#5954)
* Fix clang-tidy findings in unit-json_view_from_json.cpp

Silence misc-use-internal-linkage on the macro-generated ADL functions,
reconcile -Weffc++ with readability-redundant-member-init, use auto for
get<T>() initializers, and use value() on the optional access.

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

* Satisfy bugprone-unchecked-optional-access in unit-json_view_from_json.cpp

clang-tidy 22 also flags value(); check has_value() in the same expression.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-28 19:44:53 +01:00
Niels Lohmann da83aa92c8 Reconcile -Weffc++ and readability-redundant-member-init in unit-bson.cpp (#5953) 2026-10-28 07:11:04 +01:00
Niels Lohmann 84c5421644 Fix regression1 operator[](json_pointer) test under JSON_NO_THREAD_LOCAL (#5952)
The test relies on a copied fifo_map restarting its timestamps. Copying a
basic_json does that only on the recursive path; with JSON_NO_THREAD_LOCAL
the copy is built member by member and keeps correct timestamps, so the
premise was missing and the test failed (ci_test_no_thread_local, MinGW
clang). Copy the object_t explicitly to create the state on every path.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-27 20:31:53 +01:00
Niels Lohmann 8617d9c94c Fix test lints that are red on develop (effc++, clang-tidy) (#5946)
- unit-bson: initialize the SAX recorder's member (-Weffc++)
- unit-json_patch: build the reference document independently instead of
  copying it (performance-unnecessary-copy-initialization)
- unit-json_view_builder: use node_kind::link instead of an out-of-range
  enum cast (clang-analyzer-optin.core.EnumCastOutOfRange)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-27 17:25:18 +01:00
Niels Lohmann eb8f675bc9 docs: explain signed zero in the diff() round-trip exceptions (#5944)
Spell out that numbers comparing equal produce no operation even if one is
zero and the other negative zero, in diff.md and features/json_patch.md.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-27 17:16:08 +01:00
Niels Lohmann 78a0687147 Strong exception guarantee for operator[](json_pointer) (#5940)
* Keep the value unchanged when operator[] with a JSON pointer throws

The non-const operator[](json_pointer) is documented with strong exception
safety, but get_unchecked created intermediate values while walking the
pointer and kept them when a later reference token failed, e.g.
json j; j["/a/99999999999999999999999"_json_pointer] threw 404 and left
{"a":[]}; padding an existing array or appending with "-" behaved alike,
and so did std::length_error/std::bad_alloc from a huge index.

get_unchecked now only walks existing values up to the last reference
token. The last token's key insertion or array growth is strongly
exception safe by itself. Any other change goes through
get_unchecked_create, which records the one change it makes to an existing
value (null converted, key inserted, array grown) in a RAII guard and
reverts it if a later step throws; everything else it creates lies below
that change. The guard needs no try/catch, so JSON_NOEXCEPTION builds are
unaffected. Successful calls create the same values as before.

Docs: state the guarantee in the exceptions list and version history of
operator[], fix the complexity of the pointer overloads of operator[] and
at, and warn that padding arrays up to an untrusted index allocates memory
proportional to the index (operator[].md, untrusted_input.md).

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

* Make the strongly exception-safe pointer operator[] faster than before

The previous commit made get_unchecked strongly exception safe but slower
with GCC 16 when it creates values (up to +6 % instructions for appending
with "-"). This restructures it so that no benchmark row is slower than
before the strong guarantee, with GCC 16, Clang 22 and Apple Clang.

- get_unchecked walks existing values in one loop that inserts nothing.
  The last reference token is resolved in that walk: "-" appends with
  emplace_back(), an index grows the array with operator[], and a missing
  key is inserted with emplace_hint() at the position the walk's
  lower_bound() found, so the key is searched once.
- With std::less<string_t> or std::less<> as comparator, the walk checks
  the key at the lower bound for equality instead of equivalence, which is
  the same for these comparators and cheaper.
- get_unchecked_create (not inlined) handles all other changes. Its guard
  swaps a null value with a fresh null value instead of copying it and
  reverts the change in a non-inlined function, so a successful call pays
  one compare for it. As every null value converted afterwards is a fresh
  one, it is converted in place instead of assigning a new array or object.
- Keys are added to new objects with emplace(), which also replaces the
  basic_json::operator[] call for ordered_json.

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

* Fix rollback of pointer operator[] for unusual object and string types

Follow-up to the strong exception guarantee of the non-const
operator[](json_pointer):

- get_unchecked_create assumed that emplace() always inserts the key that
  the walk did not find. For object types whose lookup and emplace()
  disagree (e.g. a copied fifo_map), nothing was inserted, the rollback
  erased the existing member, and the walk continued with a value of the
  wrong type (assertion, type_error.305, or a crash). It now checks the
  result of emplace(), arms the rollback only if a key was inserted, and
  otherwise continues the walk with the member found, as basic_json's
  operator[] does: such pointers throw out_of_range.404 and leave the value
  unchanged, as before the strong guarantee.
- The rollback erased the inserted key by key, which converts string_t to
  object_t::key_type and may allocate inside a noexcept function
  (std::terminate on bad_alloc with custom key types). It now erases by the
  iterator emplace() returned, and shrinks a grown array with erase() at
  the end instead of resize(). The documentation states the remaining
  requirement for custom template parameters.
- Creating values no longer calls string_t::begin(), so the non-const
  operator[](json_pointer) compiles with string types that lack it (as the
  alternative string type of the tests).
- Correct the @throw lists of get_unchecked and get_unchecked_create.

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

* Address review comments on operator[](json_pointer) rollback

- undo() shrinks the array with resize() instead of erase()
- comments say what "will be" done in get_unchecked_create
- tests: avoid a clang-tidy performance-unnecessary-copy-initialization
  hit (unit-alt-string) and the word "access" in section names, which
  Flawfinder flags as race/access

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

* Let the pointer rollback guard call undo() unconditionally

The check in the destructor and JSON_HEDLEY_NEVER_INLINE on undo() made no
measurable difference: instruction counts of j[ptr] are identical with
GCC 13 -O3 and within 0.4 % with clang, timings are within noise.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-27 17:15:55 +01:00
Niels Lohmann ebf5a176c4 Fix remaining red CI on develop: Infer null dereferences, clang-tidy redundant init (#5943) 2026-10-27 14:31:31 +01:00
Niels Lohmann a47170346a docs: new design for the documentation site (#5934)
* docs: new design for the documentation site

Apply the brand to the Material for MkDocs site: Inter and JetBrains Mono
served by the site (upright and real italic), brand colours, blue header band
with the syntax pattern, wordmark in the header, new home page (hero, cards,
animated feature tour), 404 page, polish for tabs, search, footer, focus
rings, tables and code blocks, and theme features (code copy, previous/next
footer, TOC follow, search suggestions).

Draw the number railroad diagram, the parser callback events and the iterator
illustrations as inline SVGs that follow the light and dark scheme. The
generator scripts are in docs/mkdocs/scripts/figures; the feature slideshow
(json-light.svg, json-dark.svg, replacing json.gif on the home page) is built
by docs/mkdocs/scripts/slideshow. Decision nodes in five flowcharts become
hexagons, which need far less room.

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

* docs: add figures, table captions and a macro chooser

- Figures with numbered captions: SAX stepper, json_view layout and edit
  stepper, exception map, JSON pointer and patch walkers, QA pipeline,
  scaling and binary size charts, roadmap lanes, release timeline,
  integration decision tree and namespace builder
- Table captions (nj-table-caption) on 9 pages
- Compile times: modules and PCH charts, filesystem section, re-measured
  Figure 1, links between features/modules.md and compile_times.md
- Interactive macro chooser for features/arbitrary_types.md
- Link check: exclude URLs that answer the plugin with 400/401/419 or are
  dead (customers.md)

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

* docs: macro chooser generates adl_serializer for non-default-constructible types

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

* docs: cross-link concept pages and API pages in See also sections

Add See also links in both directions between the concept pages (features,
home, integration) and the API pages, write API links in code font, give every
entry a comment after a dash, and show the callback event figure on the parser
callbacks page.

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

* docs: address review comments on the new design

- Home: add a "Latest release" button
- Sponsors: update the list and group it by tier
- Features: list all feature pages on the index page
- Releases: add highlights per release, link the 4.0 roadmap, add the first commit to the timeline
- Exceptions: prefix all example messages with the exception name
- API: no code font for format names in the See also links of the to_/from_ pages
- Merge Patch: show the document before, the patch, and the result
- Replace "--" with typographic dashes, mark external links with an icon, center Mermaid diagrams

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-27 07:41:42 +01:00
Niels Lohmann 2bb2feeef4 Fix the red CI on develop (json_view pointer tokens, bson, from_json tests, Infer, IWYU) (#5942)
* json_view: pointer tokens that cannot be array indices create objects

editable_document::set() chose an array for a null parent whenever the
token consisted of digits, so "01" threw parse_error.106 and the empty
token threw, while basic_json::operator[](json_pointer) has created an
object for such tokens since #5358. This broke
unit-json_view_edit_values on develop. Use the same RFC 6901 array index
test as basic_json.

Also re-indent the unflatten test that the astyle check flagged.

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

* Fix the other red jobs on develop

- unit-bson: initialize recorder::events in its declaration (-Weffc++)
- unit-json_view_from_json: suppress -Wexit-time-destructors for the
  serialize-enum tables and -Wfloat-equal for same()
- unit-pointer_access: @infer-ignore NULLPTR_DEREFERENCE for the
  dereferences after get_ptr() that Infer reports
- json_view.hpp: IWYU no_include for the detail headers that the view
  code uses through nlohmann/json.hpp

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

* Fix GCC warnings in the json_view from_json test

GCC (-Weffc++, -Wfloat-equal) rejected unit-json_view_from_json.cpp
(ci_test_standards_gcc (20)): initialize the members of shape and
with_names, and suppress -Wfloat-equal for GCC like for clang.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-27 07:27:34 +01:00
Niels Lohmann 21ec9bd801 json_view: fewer allocations when parsing small documents (#5915)
- Size the buffer of decoded strings on its first growth from the input (a
  quarter of it plus 16 bytes, at most 4 KiB) instead of 272 bytes, so that a
  document with escapes does not grow it twice, with a zero-filled copy each
  time.
- Allocate the node index of documents with an estimate of up to 1024 nodes
  (was 256) together with the header, which saves one allocation. When the
  estimate is too low (dense numbers), that block stays unused: at most 16 KiB
  instead of 4 KiB. shrink_to_fit() cannot release it separately; the
  documentation says so.

Fresh parse of a 2.5 KB minified tweet: 993 to 958 ns (-3.5 %), traverse and
select -3 %, with no row consistently slower (Apple M1 Max, 30 rounds, three
runs). Dense numeric documents parse about 9 % faster and keep up to 16 KiB
more memory.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-27 07:22:49 +01:00
537 changed files with 39561 additions and 6369 deletions

No files matched your search

+2 -2
View File
@@ -24,11 +24,11 @@ jobs:
permissions:
actions: write
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+3 -3
View File
@@ -19,10 +19,10 @@ permissions:
jobs:
save:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -46,7 +46,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+2 -2
View File
@@ -16,11 +16,11 @@ concurrency:
jobs:
check_docs_links:
if: github.repository == 'nlohmann/json'
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
timeout-minutes: 30
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+4 -4
View File
@@ -27,7 +27,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -38,14 +38,14 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
languages: c-cpp
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
uses: github/codeql-action/autobuild@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
@@ -12,7 +12,7 @@ jobs:
comment:
# push runs on develop have no PR to comment on (and no "pr" artifact)
if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.event == 'pull_request' }}
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
permissions:
contents: read
actions: read
@@ -20,7 +20,7 @@ jobs:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+2 -2
View File
@@ -18,10 +18,10 @@ permissions:
jobs:
dependency-review:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+3 -3
View File
@@ -24,14 +24,14 @@ on:
jobs:
flawfinder:
name: Flawfinder
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -48,6 +48,6 @@ jobs:
output: 'flawfinder_results.sarif'
- name: Upload analysis results to GitHub Security tab
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
sarif_file: ${{github.workspace}}/flawfinder_results.sarif
+1 -1
View File
@@ -54,7 +54,7 @@ jobs:
timeout-minutes: 60
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+2 -2
View File
@@ -19,11 +19,11 @@ jobs:
contents: read
pull-requests: write
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+2 -2
View File
@@ -34,10 +34,10 @@ jobs:
contents: write
if: github.repository == 'nlohmann/json'
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+3 -3
View File
@@ -24,7 +24,7 @@ permissions:
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
@@ -40,7 +40,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -80,6 +80,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
sarif_file: results.sarif
+2 -2
View File
@@ -36,7 +36,7 @@ jobs:
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -65,7 +65,7 @@ jobs:
# Upload SARIF file generated in previous step
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
sarif_file: semgrep.sarif
if: always()
+2 -2
View File
@@ -8,7 +8,7 @@ permissions:
jobs:
stale:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
permissions:
issues: write
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+18 -18
View File
@@ -18,7 +18,7 @@ concurrency:
jobs:
ci_test_gcc:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: gcc:latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -80,7 +80,7 @@ jobs:
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -112,7 +112,7 @@ jobs:
target: [ci_test_single_header, ci_cppcheck, ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_reuse_compliance, ci_test_valgrind]
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -130,7 +130,7 @@ jobs:
run: cmake --build build --target ${{ matrix.target }}
ci_static_analysis_clang:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: silkeh/clang:22
strategy:
matrix:
@@ -149,7 +149,7 @@ jobs:
run: cmake --build build --target ${{ matrix.target }}
ci_cmake_options:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: ubuntu:24.04
strategy:
matrix:
@@ -178,7 +178,7 @@ jobs:
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -209,7 +209,7 @@ jobs:
fail-on-error: false
ci_test_compilers_gcc_old:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
strategy:
matrix:
compiler: ['4.8', '4.9', '5', '6']
@@ -251,7 +251,7 @@ jobs:
run: cmake --build build --target ci_test_compiler_g++-${{ matrix.compiler }}
ci_test_compilers_gcc:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
strategy:
matrix:
# older GCC docker images (4, 5, 6) fail to check out code
@@ -269,7 +269,7 @@ jobs:
run: cmake --build build --target ci_test_compiler_default
ci_test_compilers_clang:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
strategy:
matrix:
compiler: ['3.4', '3.5', '3.6', '3.7', '3.8', '3.9', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15-bullseye', '16', '17', '18', '19', '20', '21', '22', 'latest']
@@ -289,7 +289,7 @@ jobs:
run: cmake --build build --target ci_test_compiler_default
ci_test_standards_gcc:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: gcc:latest
strategy:
matrix:
@@ -306,7 +306,7 @@ jobs:
run: cmake --build build --target ci_test_gcc_cxx${{ matrix.standard }}
ci_test_standards_clang:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: silkeh/clang:latest
strategy:
matrix:
@@ -330,7 +330,7 @@ jobs:
if: ${{ matrix.stdlib == 'libstdcxx' }}
ci_cuda_example:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
@@ -356,7 +356,7 @@ jobs:
strategy:
matrix:
container: ['gcc:latest', 'silkeh/clang:latest']
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: ${{ matrix.container }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -383,7 +383,7 @@ jobs:
run: cmake --build build --target ci_module_cpp20
ci_icpc:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
# Intel discontinued the classic icc/icpc compiler in oneAPI 2024.0; this is
# Intel's own last officially published image that still includes it.
container: intel/oneapi-hpckit:2023.2.1-devel-ubuntu22.04
@@ -402,7 +402,7 @@ jobs:
run: cmake --build build --target ci_icpc
ci_icpx:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: intel/oneapi-hpckit:latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -416,7 +416,7 @@ jobs:
run: cmake --build build --target ci_icpx
ci_nvhpc:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
container: nvcr.io/nvidia/nvhpc:25.5-devel-cuda12.9-ubuntu22.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -433,7 +433,7 @@ jobs:
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -456,7 +456,7 @@ jobs:
target: [ci_test_examples, ci_test_build_documentation, ci_test_documentation_mermaid]
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
+2 -2
View File
@@ -28,7 +28,7 @@ jobs:
with:
persist-credentials: false
- name: Set up MinGW
uses: egor-tensin/setup-mingw@41b837e47d7f85214629d255b9c4bc3fcbe9fd63 # v3.0
uses: egor-tensin/setup-mingw@d54f5ef0ce585bd3fbb1f8a71b5b254f59dbf931 # v3.0
with:
platform: ${{ matrix.architecture }}
version: 12.2.0 # https://github.com/egor-tensin/setup-mingw/issues/14
@@ -153,7 +153,7 @@ jobs:
- name: Install Clang
run: curl -fsSL -o LLVM${{ matrix.version }}.exe https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.version }}/LLVM-${{ matrix.version }}-win64.exe ; 7z x LLVM${{ matrix.version }}.exe -y -o"C:/Program Files/LLVM"
- name: Set up MinGW
uses: egor-tensin/setup-mingw@41b837e47d7f85214629d255b9c4bc3fcbe9fd63 # v3.0
uses: egor-tensin/setup-mingw@d54f5ef0ce585bd3fbb1f8a71b5b254f59dbf931 # v3.0
with:
platform: x64
version: 12.2.0 # https://github.com/egor-tensin/setup-mingw/issues/14
+2 -2
View File
@@ -1408,9 +1408,9 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I
- The class contains a port of the shortest double-to-decimal conversion of [Żmij](https://github.com/vitaut/zmij) by Victor Zverovich, including the conversion of the digits to text by Xiang JunBo and the SIMD instruction sequence of Dougall Johnson, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2025 [Victor Zverovich](https://github.com/vitaut)
- The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
- The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
- The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright &copy; 2021 The fast_float authors
- The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, its digit comparison for long numbers, and its parsing of eight digits at a time from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright &copy; 2021 The fast_float authors
- The view's parser (`<nlohmann/json_view.hpp>`) contains techniques and code adapted from [yyjson](https://github.com/ibireme/yyjson) by YaoYuan, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above): table-driven decoding of `\u` escapes and fixed-offset unrolled checks.
- The view's parser (`<nlohmann/json_view.hpp>`) validates non-ASCII strings with the vector UTF-8 check of [simdjson](https://github.com/simdjson/simdjson) by Daniel Lemire, Geoff Langdale, John Keiser, and contributors (its "lookup4" algorithm and tables, after J. Keiser and D. Lemire, "Validating UTF-8 In Less Than One Instruction Per Byte", 2021), which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here) and the Apache 2.0 License. Copyright &copy; 2018-2025 The simdjson authors
- The class's lexer and the view's parser (`<nlohmann/json_view.hpp>`) validate non-ASCII strings with the vector UTF-8 check of [simdjson](https://github.com/simdjson/simdjson) by Daniel Lemire, Geoff Langdale, John Keiser, and contributors (its "lookup4" algorithm and tables, after J. Keiser and D. Lemire, "Validating UTF-8 In Less Than One Instruction Per Byte", 2021), which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here) and the Apache 2.0 License. Copyright &copy; 2018-2025 The simdjson authors
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
+3 -3
View File
@@ -348,20 +348,20 @@ add_custom_target(ci_test_no_thread_local
add_custom_target(ci_test_coverage
COMMAND CXX=g++ ${CMAKE_COMMAND}
-DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="--coverage;-fprofile-arcs;-ftest-coverage"
-DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="--coverage;-fprofile-arcs;-ftest-coverage;-fvar-tracking-assignments"
-DJSON_BuildTests=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage
COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
COMMAND CXX=g++ ${CMAKE_COMMAND}
-DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="-m32;--coverage;-fprofile-arcs;-ftest-coverage"
-DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="-m32;--coverage;-fprofile-arcs;-ftest-coverage;-fvar-tracking-assignments"
-DJSON_BuildTests=ON -DJSON_32bitTest=ONLY
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage32
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage32
COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage32 && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc branch_coverage=1 --rc geninfo_unexecuted_blocks=1 --ignore-errors mismatch --ignore-errors unused --ignore-errors inconsistent
COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc branch_coverage=1 --ignore-errors mismatch --ignore-errors unused --ignore-errors inconsistent
COMMAND ${LCOV_TOOL} -e json.info ${SRC_FILES} --output-file json.info.filtered --rc branch_coverage=1 --ignore-errors unused --ignore-errors inconsistent
COMMAND ${CMAKE_SOURCE_DIR}/tests/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept
COMMAND ${GENHTML_TOOL} --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage --ignore-errors inconsistent json.info.filtered.noexcept
+3 -1
View File
@@ -178,8 +178,10 @@ function(_json_test_add_test test_name file main cxx_standard)
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# under Valgrind the slowest tests take close to 25 minutes, so ctest's
# default timeout of 1500 seconds leaves no headroom
set_tests_properties(${test_target}_valgrind PROPERTIES
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA TIMEOUT 3600
)
endif()
endfunction()
@@ -30,7 +30,7 @@ class (either explicitly or via the conversion operators).
## Return value
1. (none) -- the converted value is written to the output parameter `val`.
1. (none) — the converted value is written to the output parameter `val`.
2. the JSON value `j` converted to `TargetType`
## Examples
@@ -67,7 +67,9 @@ class (either explicitly or via the conversion operators).
## See also
- [to_json](to_json.md)
- [`to_json`](to_json.md) - convert a C++ value to JSON
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) - write your own `from_json` and `to_json` functions
- [Converting values](../../features/conversions.md) - overview of `get`, `get_to` and implicit conversions
## Version history
+4 -4
View File
@@ -33,10 +33,10 @@ struct adl_serializer {
## See also
- [Arbitrary type conversions](../../features/arbitrary_types.md) - how to make your types convertible
- [**get**](../basic_json/get.md) / [**get_to**](../basic_json/get_to.md) - convert a JSON value to a C++ type
- [**basic_json**](../basic_json/basic_json.md) - construct a JSON value from a C++ value
- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE**](../macros/nlohmann_define_type_intrusive.md) - generate the conversion functions for a type
- [Specializing enum conversion](../../features/enum_conversion.md)
- [`get`](../basic_json/get.md) - / [`get_to`](../basic_json/get_to.md) - convert a JSON value to a C++ type
- [`basic_json`](../basic_json/basic_json.md) - construct a JSON value from a C++ value
- [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](../macros/nlohmann_define_type_intrusive.md) - generate the conversion functions for a type
- [Specializing enum conversion](../../features/enum_conversion.md) - serializing enums as JSON strings
## Version history
@@ -36,7 +36,9 @@ This function is usually called by the constructors of the [basic_json](../basic
## See also
- [from_json](from_json.md)
- [`from_json`](from_json.md) - convert JSON to a C++ value
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) - write your own `from_json` and `to_json` functions
- [Converting values](../../features/conversions.md) - overview of `get`, `get_to` and implicit conversions
## Version history
+8 -3
View File
@@ -148,15 +148,20 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
## See also
- [parse](parse.md) - deserialize from a compatible input
- [sax_parse](sax_parse.md) - parse input using the SAX interface
- [operator>>](../operator_gtgt.md) - deserialize from stream
- [`parse`](parse.md) - deserialize from a compatible input
- [`sax_parse`](sax_parse.md) - parse input using the SAX interface
- [`operator>>`](../operator_gtgt.md) - deserialize from stream
- [`JSON_STRICT_NUL_HANDLING`](../macros/json_strict_nul_handling.md) - opt in to rejecting a NUL byte in the input
instead of treating it as end of input
- [`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md) - read a `std::istream` one character
at a time
- [`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) - read a `FILE*` with the locking stdio
functions
- [Parsing](../../features/parsing/index.md) - overview of the parsing functions
- [Comments](../../features/comments.md) - ignore `//` and `/* */` comments while parsing
- [Trailing Commas](../../features/trailing_commas.md) - accept trailing commas in arrays and objects
- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - handling parse errors and locating them in the input
- [Parsing Untrusted Input](../../features/parsing/untrusted_input.md) - limits and checks for input you do not control
## Version history
+2 -2
View File
@@ -29,9 +29,9 @@ Linear in the size of `init`.
This function is only needed to express two edge cases that cannot be realized with the initializer list constructor
([`basic_json(initializer_list_t, bool, value_t)`](basic_json.md)). These cases are:
1. creating an array whose elements are all pairs whose first element is a string -- in this case, the initializer list
1. creating an array whose elements are all pairs whose first element is a string — in this case, the initializer list
constructor would create an object, taking the first elements as keys
2. creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty
2. creating an empty array — passing the empty initializer list to the initializer list constructor yields an empty
object
## Examples
+6 -4
View File
@@ -69,10 +69,12 @@ Arrays are stored as pointers in a `basic_json` type. That is, for any access to
## See also
- [object_t](object_t.md) the type used to store JSON objects
- [binary_t](binary_t.md) the type used to store binary values
- [is_array](is_array.md) checks whether the JSON value is an array
- [max_size](max_size.md) returns the maximum possible number of elements
- [`object_t`](object_t.md) - the type used to store JSON objects
- [`binary_t`](binary_t.md) - the type used to store binary values
- [`is_array`](is_array.md) - checks whether the JSON value is an array
- [`max_size`](max_size.md) - returns the maximum possible number of elements
- [Types](../../features/types/index.md) - how arrays are stored
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `ArrayType` template parameter
## Version history
@@ -46,7 +46,8 @@ The function is equivalent to `static_cast<json_base_class_t&>(j)` (or `static_c
## See also
- [json_base_class_t](json_base_class_t.md) - type of the custom base class
- [`json_base_class_t`](json_base_class_t.md) - type of the custom base class
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `CustomBaseClass` template parameter
## Version history
+8 -5
View File
@@ -90,7 +90,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
1. Constant.
2. Logarithmic in the size of the container.
3. Logarithmic in the size of the container.
4. Logarithmic in the size of the container.
4. Linear in the number of reference tokens of `ptr`; for each of them, logarithmic in the size of the object, or
constant for an array.
## Notes
@@ -230,10 +231,12 @@ Strong exception safety: if an exception occurs, the original value stays intact
## See also
- documentation on [checked access](../../features/element_access/checked_access.md)
- [`operator[]`](operator%5B%5D.md) for unchecked access by reference
- [`value`](value.md) for access with default value
- [basic_json_view::at](../basic_json_view/at.md) - the same access on a zero-copy view
- [Checked access](../../features/element_access/checked_access.md) - element access with range checking
- [`operator[]`](operator%5B%5D.md) - unchecked access by reference
- [`value`](value.md) - access with default value
- [`basic_json_view::at`](../basic_json_view/at.md) - the same access on a zero-copy view
- [Element Access](../../features/element_access/index.md) - overview of all ways to access elements
- [JSON Pointer](../../features/json_pointer.md) - access nested values with a pointer
## Version history
+3 -2
View File
@@ -57,8 +57,9 @@ Constant.
## See also
- [front](front.md) to access the first element
- [basic_json_view::back](../basic_json_view/back.md) - the same access on a zero-copy view
- [`front`](front.md) - to access the first element
- [`basic_json_view::back`](../basic_json_view/back.md) - the same access on a zero-copy view
- [Element Access](../../features/element_access/index.md) - overview of all ways to access elements
## Version history
+14 -10
View File
@@ -52,7 +52,7 @@ basic_json(basic_json&& other) noexcept;
The postcondition of this constructor can be restored by calling [`clear()`](clear.md).
2. Create a `#!json null` JSON value. It either takes a null pointer as parameter (explicitly creating `#!json null`)
or no parameter (implicitly creating `#!json null`). The passed null pointer itself is not read -- it is only used to
or no parameter (implicitly creating `#!json null`). The passed null pointer itself is not read — it is only used to
choose the right constructor.
3. This is a "catch all" constructor for all compatible JSON types; that is, types for which a `to_json()` method
@@ -113,19 +113,22 @@ basic_json(basic_json&& other) noexcept;
```mermaid
flowchart TD
A(["initializer_list init"]) --> B{"empty, or every element is a 2-element<br/>array whose first element is a string?"}
B -->|"yes"| C{"type_deduction"}
B -->|"no"| D{"type_deduction"}
A(["initializer_list init"]) --> B{{"empty, or every element is a 2-element<br/>array whose first element is a string?"}}
B -->|"yes"| C{{"type_deduction"}}
B -->|"no"| D{{"type_deduction"}}
C -->|"true"| OBJ["create object"]
C -->|"false"| E{"manual_type"}
C -->|"false"| E{{"manual_type"}}
E -->|"object"| OBJ
E -->|"array"| ARR["create array"]
D -->|"true"| ARR
D -->|"false"| F{"manual_type"}
D -->|"false"| F{{"manual_type"}}
F -->|"array"| ARR
F -->|"object"| ERR["throw type_error.301"]
```
<p class="nj-caption" markdown>Decision flow for an initializer list: hexagons are checks, edge labels are their
outcomes, and rectangles are the resulting value or exception.</p>
The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:
1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object.
@@ -473,12 +476,13 @@ basic_json(basic_json&& other) noexcept;
## See also
- [array](array.md) create a JSON array value, forcing array creation from an initializer list even when it looks like
- [`array`](array.md) - create a JSON array value, forcing array creation from an initializer list even when it looks like
an object
- [object](object.md) create a JSON object value, forcing object creation from an initializer list
- [binary](binary.md) create a JSON binary array value
- [operator=](operator=.md) copy assignment operator
- [`object`](object.md) - create a JSON object value, forcing object creation from an initializer list
- [`binary`](binary.md) - create a JSON binary array value
- [`operator=`](operator=.md) - copy assignment operator
- [Creating JSON values](../../features/creating_values.md) - the article on creating JSON values
- [Converting values](../../features/conversions.md) - which C++ types can be converted
## Version history
+11 -6
View File
@@ -7,7 +7,12 @@ const_iterator begin() const noexcept;
Returns an iterator to the first element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`begin()` points to the first element and `end()` to the position after the last element;
the dashed cell is the past-the-last position, which must not be dereferenced.</p>
## Return value
@@ -39,12 +44,12 @@ Constant.
## See also
- [end](end.md) returns an iterator to one past the last element
- [cbegin](cbegin.md) returns a const iterator to the first element
- [rbegin](rbegin.md) returns a reverse iterator to the last element
- [items](items.md) returns an iteration proxy to access keys and values during range-based for loops
- [`end`](end.md) - returns an iterator to one past the last element
- [`cbegin`](cbegin.md) - returns a const iterator to the first element
- [`rbegin`](rbegin.md) - returns a reverse iterator to the last element
- [`items`](items.md) - returns an iteration proxy to access keys and values during range-based for loops
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::begin](../basic_json_view/begin.md) - the same iteration on a zero-copy view (in document order,
- [`basic_json_view::begin`](../basic_json_view/begin.md) - the same iteration on a zero-copy view (in document order,
not sorted by key)
## Version history
+5 -4
View File
@@ -63,10 +63,11 @@ initialization of a binary array type, for backwards compatibility and so it doe
## See also
- [binary_t](binary_t.md) type for binary values
- [get_binary](get_binary.md) get a reference to the stored binary value
- [is_binary](is_binary.md) return whether the value is binary
- [byte_container_with_subtype](../byte_container_with_subtype/index.md) container for binary values with subtype
- [Binary formats](../../features/binary_formats/index.md) - formats that can store binary values
- [`binary_t`](binary_t.md) - type for binary values
- [`get_binary`](get_binary.md) - get a reference to the stored binary value
- [`is_binary`](is_binary.md) - return whether the value is binary
- [`byte_container_with_subtype`](../byte_container_with_subtype/index.md) - container for binary values with subtype
- [Binary Values](../../features/binary_values.md) - the article on binary values
## Version history
+4 -2
View File
@@ -41,7 +41,7 @@ represent a byte array in modern C++.
[`byte_container_with_subtype`](../byte_container_with_subtype/index.md) derives directly from it. Its
`value_type` must additionally be exactly one byte wide (e.g., `std::uint8_t`/`char`/`std::byte`): the binary
serializers (CBOR, MessagePack, BSON, UBJSON) read and write the container's raw bytes via
`reinterpret_cast`, which is only correct for byte-sized elements -- a container like
`reinterpret_cast`, which is only correct for byte-sized elements — a container like
`#!cpp std::vector<std::intptr_t>` will not work as `BinaryType`. The elements must be stored contiguously, and
the binary readers additionally require `resize()` and `operator[]`. See
[Template Parameter Requirements](../../features/types/template_parameters.md#binarytype) for the full list.
@@ -118,7 +118,9 @@ type `#!cpp binary_t*` must be dereferenced.
## See also
- [byte_container_with_subtype](../byte_container_with_subtype/index.md)
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [Binary formats](../../features/binary_formats/index.md) - formats that can store binary values
- [`byte_container_with_subtype`](../byte_container_with_subtype/index.md) - container type used by binary values
## Version history
+3 -1
View File
@@ -47,7 +47,9 @@ Boolean values are stored directly inside a `basic_json` type.
## See also
- [is_boolean](is_boolean.md) checks whether the JSON value is a boolean
- [`is_boolean`](is_boolean.md) - checks whether the JSON value is a boolean
- [Types](../../features/types/index.md) - how booleans are stored
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `BooleanType` template parameter
## Version history
+10 -5
View File
@@ -6,7 +6,12 @@ const_iterator cbegin() const noexcept;
Returns an iterator to the first element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`cbegin()` points to the first element, like `begin()`, and `end()` to the position after
the last element; the dashed cell is the past-the-last position, which must not be dereferenced.</p>
## Return value
@@ -38,11 +43,11 @@ Constant.
## See also
- [begin](begin.md) returns an iterator to the first element
- [cend](cend.md) returns a const iterator to one past the last element
- [crbegin](crbegin.md) returns a const reverse iterator to the last element
- [`begin`](begin.md) - returns an iterator to the first element
- [`cend`](cend.md) - returns a const iterator to one past the last element
- [`crbegin`](crbegin.md) - returns a const reverse iterator to the last element
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::cbegin](../basic_json_view/cbegin.md) - the same iteration on a zero-copy view
- [`basic_json_view::cbegin`](../basic_json_view/cbegin.md) - the same iteration on a zero-copy view
## Version history
@@ -42,8 +42,9 @@ store
## See also
- [from_cbor](from_cbor.md) deserializes a JSON value from CBOR
- [input_format_t](input_format_t.md) the enumeration of supported input formats
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [`from_cbor`](from_cbor.md) - deserializes a JSON value from CBOR
- [`input_format_t`](input_format_t.md) - the enumeration of supported input formats
- [CBOR](../../features/binary_formats/cbor.md) - the article on the CBOR format
## Version history
+10 -5
View File
@@ -6,7 +6,12 @@ const_iterator cend() const noexcept;
Returns an iterator to one past the last element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`cend()` points to the position after the last element, like `end()`, and `begin()` to
the first element; the dashed cell is the past-the-last position, which must not be dereferenced.</p>
## Return value
@@ -38,11 +43,11 @@ Constant.
## See also
- [end](end.md) returns an iterator to one past the last element
- [cbegin](cbegin.md) returns a const iterator to the first element
- [crend](crend.md) returns a const reverse iterator to one before the first element
- [`end`](end.md) - returns an iterator to one past the last element
- [`cbegin`](cbegin.md) - returns a const iterator to the first element
- [`crend`](crend.md) - returns a const reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::cend](../basic_json_view/cend.md) - the same iteration on a zero-copy view
- [`basic_json_view::cend`](../basic_json_view/cend.md) - the same iteration on a zero-copy view
## Version history
+3 -2
View File
@@ -54,8 +54,9 @@ All iterators, pointers, and references related to this container are invalidate
## See also
- [erase](erase.md) removes elements from a JSON value
- [empty](empty.md) checks whether the JSON value has no elements
- [`erase`](erase.md) - removes elements from a JSON value
- [`empty`](empty.md) - checks whether the JSON value has no elements
- [Modifying values](../../features/modifying_values.md) - the article on modifying values
## Version history
+4 -3
View File
@@ -141,9 +141,10 @@ Strong exception safety: if an exception occurs, the original value stays intact
## See also
- [find](find.md) find a value in an object
- [count](count.md) returns the number of occurrences of a key
- [basic_json_view::contains](../basic_json_view/contains.md) - the same check on a zero-copy view
- [`find`](find.md) - find a value in an object
- [`count`](count.md) - returns the number of occurrences of a key
- [`basic_json_view::contains`](../basic_json_view/contains.md) - the same check on a zero-copy view
- [Element Access](../../features/element_access/index.md#does-this-key-exist) - how to test whether a key exists
## Version history
+4 -3
View File
@@ -85,9 +85,10 @@ Logarithmic in the size of the JSON object.
## See also
- [find](find.md) find a value in an object
- [contains](contains.md) checks whether a key exists
- [basic_json_view::count](../basic_json_view/count.md) - the same check on a zero-copy view
- [`find`](find.md) - find a value in an object
- [`contains`](contains.md) - checks whether a key exists
- [`basic_json_view::count`](../basic_json_view/count.md) - the same check on a zero-copy view
- [Element Access](../../features/element_access/index.md#does-this-key-exist) - how to test whether a key exists
## Version history
+10 -4
View File
@@ -6,7 +6,13 @@ const_reverse_iterator crbegin() const noexcept;
Returns an iterator to the reverse-beginning; that is, the last element.
![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-rbegin-rend.svg"
</div>
<p class="nj-caption" markdown>`crbegin()` points to the last element, like `rbegin()`, and `rend()` to the position
before the first element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows
link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.</p>
## Return value
@@ -38,9 +44,9 @@ Constant.
## See also
- [crend](crend.md) returns a const reverse iterator to one before the first element
- [rbegin](rbegin.md) returns a reverse iterator to the last element
- [cbegin](cbegin.md) returns a const iterator to the first element
- [`crend`](crend.md) - returns a const reverse iterator to one before the first element
- [`rbegin`](rbegin.md) - returns a reverse iterator to the last element
- [`cbegin`](cbegin.md) - returns a const iterator to the first element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
+10 -4
View File
@@ -7,7 +7,13 @@ const_reverse_iterator crend() const noexcept;
Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder,
attempting to access it results in undefined behavior.
![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-rbegin-rend.svg"
</div>
<p class="nj-caption" markdown>`crend()` points to the position before the first element, like `rend()`, and `rbegin()`
to the last element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link
each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.</p>
## Return value
@@ -39,9 +45,9 @@ Constant.
## See also
- [crbegin](crbegin.md) returns a const reverse iterator to the last element
- [rend](rend.md) returns a reverse iterator to one before the first element
- [cend](cend.md) returns a const iterator to one past the last element
- [`crbegin`](crbegin.md) - returns a const reverse iterator to the last element
- [`rend`](rend.md) - returns a reverse iterator to one before the first element
- [`cend`](cend.md) - returns a const iterator to one past the last element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
@@ -32,8 +32,10 @@ The actual comparator used depends on [`object_t`](object_t.md) and can be obtai
## See also
- [object_comparator_t](object_comparator_t.md) the comparator actually used by `object_t`
- [object_t](object_t.md) the type used to store JSON objects
- [`object_comparator_t`](object_comparator_t.md) - the comparator actually used by `object_t`
- [`object_t`](object_t.md) - the type used to store JSON objects
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `ObjectType` template parameter
- [Object order](../../features/object_order.md) - preserve the insertion order of keys
## Version history
+10 -8
View File
@@ -19,9 +19,10 @@ The equality holds up to [`operator==`](operator_eq.md), so it has the following
- A value that is not equal to itself cannot round-trip. This applies to `NaN` (also nested in an array or object) and
to [discarded](is_discarded.md) values: `diff` emits a `replace` operation for them. A `NaN` in the patch is
serialized as `#!json null`, so a patch that was dumped and parsed again would set `#!json null`.
- Numbers that compare equal produce no operation, even if their types or signs differ: `diff(1, 1.0)`,
`diff(1u, 1)` (unsigned and signed integer) and `diff(0.0, -0.0)` all return `#!json []`. The patched value is then
the `source` and keeps its number type.
- Numbers that compare equal produce no operation, even if their types differ or if one is zero and the other is
negative zero: `diff(1, 1.0)` (integer and floating-point), `diff(1u, 1)` (unsigned and signed integer) and
`diff(0.0, -0.0)` (positive and negative zero) all return `#!json []`. The patched value is then the `source` and
keeps its number type and sign.
## Parameters
@@ -92,11 +93,12 @@ operations times the length of their paths, so a small change deep inside a valu
## See also
- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
- [patch](patch.md) applies a JSON Patch
- [patch_inplace](patch_inplace.md) applies a JSON Patch in place
- [merge_patch](merge_patch.md) applies a JSON Merge Patch
- [merge_diff](merge_diff.md) creates a diff as a JSON Merge Patch
- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - specification of JSON Patch
- [`patch`](patch.md) - applies a JSON Patch
- [`patch_inplace`](patch_inplace.md) - applies a JSON Patch in place
- [`merge_patch`](merge_patch.md) - applies a JSON Merge Patch
- [`merge_diff`](merge_diff.md) - creates a diff as a JSON Merge Patch
- [JSON Patch and Diff](../../features/json_patch.md) - the article on JSON Patch
## Version history
+3 -3
View File
@@ -89,9 +89,9 @@ Binary values are serialized as an object containing two keys:
## See also
- [to_string](to_string.md) returns a string representation of a JSON value
- [operator<<](../operator_ltlt.md) serialize to stream
- [`basic_json_view::dump`](../basic_json_view/dump.md) the corresponding function of `basic_json_view`, serializing
- [`to_string`](to_string.md) - returns a string representation of a JSON value
- [`operator<<`](../operator_ltlt.md) - serialize to stream
- [`basic_json_view::dump`](../basic_json_view/dump.md) - the corresponding function of `basic_json_view`, serializing
directly from a flat index without building a `basic_json` value
- [Serialization](../../features/serialization.md) - the serialization article
+2 -2
View File
@@ -63,8 +63,8 @@ Logarithmic in the size of the container, O(log(`size()`)).
## See also
- [emplace_back](emplace_back.md) add a value to an array
- [insert](insert.md) add values to an array/object
- [`emplace_back`](emplace_back.md) - add a value to an array
- [`insert`](insert.md) - add values to an array/object
- [Modifying values](../../features/modifying_values.md) - the article on modifying values
## Version history
@@ -61,8 +61,8 @@ Amortized constant.
## See also
- [operator+=](operator+=.md) add a value to an array/object
- [push_back](push_back.md) add a value to an array/object
- [`operator+=`](operator+=.md) - add a value to an array/object
- [`push_back`](push_back.md) - add a value to an array/object
- [Modifying values](../../features/modifying_values.md) - the article on modifying values
## Version history
+4 -4
View File
@@ -41,7 +41,7 @@ bool empty() const noexcept
## Notes
This function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container
This function does not return whether a string stored as JSON value is empty — it returns whether the JSON container
itself is empty which is `#!cpp false` in the case of a string.
## Examples
@@ -62,9 +62,9 @@ itself is empty which is `#!cpp false` in the case of a string.
## See also
- [size](size.md) returns the number of elements
- [clear](clear.md) clears the content and resets the value to the default value
- [basic_json_view::empty](../basic_json_view/empty.md) - the same check on a zero-copy view
- [`size`](size.md) - returns the number of elements
- [`clear`](clear.md) - clears the content and resets the value to the default value
- [`basic_json_view::empty`](../basic_json_view/empty.md) - the same check on a zero-copy view
## Version history
+10 -5
View File
@@ -7,7 +7,12 @@ const_iterator end() const noexcept;
Returns an iterator to one past the last element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`end()` points to the position after the last element and `begin()` to the first element;
the dashed cell is the past-the-last position, which must not be dereferenced.</p>
## Return value
@@ -39,11 +44,11 @@ Constant.
## See also
- [begin](begin.md) returns an iterator to the first element
- [cend](cend.md) returns a const iterator to one past the last element
- [rend](rend.md) returns a reverse iterator to one before the first element
- [`begin`](begin.md) - returns an iterator to the first element
- [`cend`](cend.md) - returns a const iterator to one past the last element
- [`rend`](rend.md) - returns a reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::end](../basic_json_view/end.md) - the same iteration on a zero-copy view
- [`basic_json_view::end`](../basic_json_view/end.md) - the same iteration on a zero-copy view
## Version history
+3 -2
View File
@@ -60,8 +60,9 @@ Constant.
## See also
- [start_pos](start_pos.md) to access the start position
- [JSON_DIAGNOSTIC_POSITIONS](../macros/json_diagnostic_positions.md) for an overview of the diagnostic positions
- [`start_pos`](start_pos.md) - to access the start position
- [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) - overview of the supported conversions
- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - handling parse errors and locating them in the input
## Version history
+2 -2
View File
@@ -204,8 +204,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
## See also
- [clear](clear.md) clears the contents
- [insert](insert.md) add values to an array/object
- [`clear`](clear.md) - clears the contents
- [`insert`](insert.md) - add values to an array/object
- [Modifying values](../../features/modifying_values.md) - the article on modifying values
## Version history
@@ -61,7 +61,7 @@ keep
## See also
- [dump](dump.md) serializes a JSON value, with an `error_handler_t` parameter to configure invalid UTF-8 handling
- [`dump`](dump.md) - serializes a JSON value, with an `error_handler_t` parameter to configure invalid UTF-8 handling
- [Handling invalid UTF-8](../../features/serialization.md#handling-invalid-utf-8) - the article on handling invalid UTF-8
## Version history
+8 -1
View File
@@ -40,6 +40,9 @@ classDiagram
style json_exception fill:#CCCCFF
```
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
base class, and the highlighted box is `basic_json::exception`.</p>
Subclasses:
- [`parse_error`](parse_error.md) for exceptions indicating a parse error
@@ -80,7 +83,11 @@ constructor.
## See also
[List of exceptions](../../home/exceptions.md)
- [List of exceptions](../../home/exceptions.md) - overview of all exceptions thrown by the library
- [Working Without Exceptions](../../features/no_exceptions.md) - using the library without exceptions
- [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) - extended exception messages with the path of the failing value
- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - parsing alternatives that do not throw
- [Debugging](../../home/debugging.md) - debugging aids
## Version history
+4 -3
View File
@@ -91,10 +91,11 @@ Logarithmic in the size of the JSON object.
## See also
- [count](count.md) returns the number of occurrences of a key
- [contains](contains.md) checks whether a key exists
- [basic_json_view::find](../basic_json_view/find.md) - the same lookup on a zero-copy view (a duplicate key resolves
- [`count`](count.md) - returns the number of occurrences of a key
- [`contains`](contains.md) - checks whether a key exists
- [`basic_json_view::find`](../basic_json_view/find.md) - the same lookup on a zero-copy view (a duplicate key resolves
to the first member, whereas `parse()` keeps the last)
- [Element Access](../../features/element_access/index.md#does-this-key-exist) - how to test whether a key exists
## Version history
+2 -1
View File
@@ -58,7 +58,8 @@ Empty objects and arrays are flattened to `#!json null` and will not be reconstr
## See also
- [unflatten](unflatten.md) the reverse function
- [`unflatten`](unflatten.md) - the reverse function
- [JSON Pointer](../../features/json_pointer.md#flatten-unflatten) - the article on JSON Pointer and flattening
## Version history
+2 -2
View File
@@ -86,8 +86,8 @@ std::string format_as(const BasicJsonType& j)
## See also
- [dump](dump.md)
- [std::formatter<basic_json>](std_formatter.md) - the `std::format` (C++20) equivalent
- [`dump`](dump.md) - serialize a JSON value to a string
- [`std::formatter<basic_json>`](std_formatter.md) - the `std::format` (C++20) equivalent
- [Serialization](../../features/serialization.md) - the serialization article
## Version history
+10 -6
View File
@@ -110,12 +110,16 @@ Linear in the size of the input.
## See also
- [to_bjdata](to_bjdata.md) create a BJData serialization of a JSON value
- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format
- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format
- [from_bson](from_bson.md) create a JSON value from an input in BSON format
- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format
- [from_bon8](from_bon8.md) create a JSON value from an input in BON8 format
- [BJData](../../features/binary_formats/bjdata.md) - the format, its byte layout and how values are mapped
- [Binary formats](../../features/binary_formats/index.md) - overview and comparison of the supported binary formats
- [Parsing untrusted input](../../features/parsing/untrusted_input.md) - limits and safe handling of hostile data
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [`to_bjdata`](to_bjdata.md) - create a BJData serialization of a JSON value
- [`from_cbor`](from_cbor.md) - create a JSON value from an input in CBOR format
- [`from_msgpack`](from_msgpack.md) - create a JSON value from an input in MessagePack format
- [`from_bson`](from_bson.md) - create a JSON value from an input in BSON format
- [`from_ubjson`](from_ubjson.md) - create a JSON value from an input in UBJSON format
- [`from_bon8`](from_bon8.md) - create a JSON value from an input in BON8 format
## Version history
+9 -6
View File
@@ -101,12 +101,15 @@ Linear in the size of the input.
## See also
- [to_bon8](to_bon8.md) create a BON8 serialization of a JSON value
- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format
- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format
- [from_bson](from_bson.md) create a JSON value from an input in BSON format
- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format
- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format
- [BON8](../../features/binary_formats/bon8.md) - the format, its byte layout and how values are mapped
- [Binary formats](../../features/binary_formats/index.md) - overview and comparison of the supported binary formats
- [Parsing untrusted input](../../features/parsing/untrusted_input.md) - limits and safe handling of hostile data
- [`to_bon8`](to_bon8.md) - create a BON8 serialization of a JSON value
- [`from_cbor`](from_cbor.md) - create a JSON value from an input in CBOR format
- [`from_msgpack`](from_msgpack.md) - create a JSON value from an input in MessagePack format
- [`from_bson`](from_bson.md) - create a JSON value from an input in BSON format
- [`from_ubjson`](from_ubjson.md) - create a JSON value from an input in UBJSON format
- [`from_bjdata`](from_bjdata.md) - create a JSON value from an input in BJData format
## Version history
+11 -7
View File
@@ -109,13 +109,17 @@ Linear in the size of the input.
## See also
- [BSON specification](http://bsonspec.org/spec.html)
- [to_bson](to_bson.md) for the analogous serialization
- [from_cbor](from_cbor.md) for the related CBOR format
- [from_msgpack](from_msgpack.md) for the related MessagePack format
- [from_ubjson](from_ubjson.md) for the related UBJSON format
- [from_bjdata](from_bjdata.md) for the related BJData format
- [from_bon8](from_bon8.md) for the related BON8 format
- [BSON](../../features/binary_formats/bson.md) - the format, its byte layout and how values are mapped
- [Binary formats](../../features/binary_formats/index.md) - overview and comparison of the supported binary formats
- [Parsing untrusted input](../../features/parsing/untrusted_input.md) - limits and safe handling of hostile data
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [BSON specification](http://bsonspec.org/spec.html) - specification of the BSON format
- [`to_bson`](to_bson.md) - the analogous serialization
- [`from_cbor`](from_cbor.md) - the related CBOR format
- [`from_msgpack`](from_msgpack.md) - the related MessagePack format
- [`from_ubjson`](from_ubjson.md) - the related UBJSON format
- [`from_bjdata`](from_bjdata.md) - the related BJData format
- [`from_bon8`](from_bon8.md) - the related BON8 format
## Version history
+10 -6
View File
@@ -122,12 +122,16 @@ Linear in the size of the input.
## See also
- [to_cbor](to_cbor.md) create a CBOR serialization of a JSON value
- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format
- [from_bson](from_bson.md) create a JSON value from an input in BSON format
- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format
- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format
- [from_bon8](from_bon8.md) create a JSON value from an input in BON8 format
- [CBOR](../../features/binary_formats/cbor.md) - the format, its byte layout and how values are mapped
- [Binary formats](../../features/binary_formats/index.md) - overview and comparison of the supported binary formats
- [Parsing untrusted input](../../features/parsing/untrusted_input.md) - limits and safe handling of hostile data
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [`to_cbor`](to_cbor.md) - create a CBOR serialization of a JSON value
- [`from_msgpack`](from_msgpack.md) - create a JSON value from an input in MessagePack format
- [`from_bson`](from_bson.md) - create a JSON value from an input in BSON format
- [`from_ubjson`](from_ubjson.md) - create a JSON value from an input in UBJSON format
- [`from_bjdata`](from_bjdata.md) - create a JSON value from an input in BJData format
- [`from_bon8`](from_bon8.md) - create a JSON value from an input in BON8 format
## Version history
@@ -107,12 +107,16 @@ Linear in the size of the input.
## See also
- [to_msgpack](to_msgpack.md) create a MessagePack serialization of a JSON value
- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format
- [from_bson](from_bson.md) create a JSON value from an input in BSON format
- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format
- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format
- [from_bon8](from_bon8.md) create a JSON value from an input in BON8 format
- [MessagePack](../../features/binary_formats/messagepack.md) - the format, its byte layout and how values are mapped
- [Binary formats](../../features/binary_formats/index.md) - overview and comparison of the supported binary formats
- [Parsing untrusted input](../../features/parsing/untrusted_input.md) - limits and safe handling of hostile data
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [`to_msgpack`](to_msgpack.md) - create a MessagePack serialization of a JSON value
- [`from_cbor`](from_cbor.md) - create a JSON value from an input in CBOR format
- [`from_bson`](from_bson.md) - create a JSON value from an input in BSON format
- [`from_ubjson`](from_ubjson.md) - create a JSON value from an input in UBJSON format
- [`from_bjdata`](from_bjdata.md) - create a JSON value from an input in BJData format
- [`from_bon8`](from_bon8.md) - create a JSON value from an input in BON8 format
## Version history
+10 -6
View File
@@ -114,12 +114,16 @@ Linear in the size of the input.
## See also
- [to_ubjson](to_ubjson.md) create a UBJSON serialization of a JSON value
- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format
- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format
- [from_bson](from_bson.md) create a JSON value from an input in BSON format
- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format
- [from_bon8](from_bon8.md) create a JSON value from an input in BON8 format
- [UBJSON](../../features/binary_formats/ubjson.md) - the format, its byte layout and how values are mapped
- [Binary formats](../../features/binary_formats/index.md) - overview and comparison of the supported binary formats
- [Parsing untrusted input](../../features/parsing/untrusted_input.md) - limits and safe handling of hostile data
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [`to_ubjson`](to_ubjson.md) - create a UBJSON serialization of a JSON value
- [`from_cbor`](from_cbor.md) - create a JSON value from an input in CBOR format
- [`from_msgpack`](from_msgpack.md) - create a JSON value from an input in MessagePack format
- [`from_bson`](from_bson.md) - create a JSON value from an input in BSON format
- [`from_bjdata`](from_bjdata.md) - create a JSON value from an input in BJData format
- [`from_bon8`](from_bon8.md) - create a JSON value from an input in BON8 format
## Version history
+3 -2
View File
@@ -50,9 +50,10 @@ Constant.
## See also
- [back](back.md) to access the last element
- [basic_json_view::front](../basic_json_view/front.md) - the same access on a zero-copy view (document order, not
- [`back`](back.md) - to access the last element
- [`basic_json_view::front`](../basic_json_view/front.md) - the same access on a zero-copy view (document order, not
sorted; duplicate keys are visited)
- [Element Access](../../features/element_access/index.md) - overview of all ways to access elements
## Version history
+16 -5
View File
@@ -120,6 +120,16 @@ overload (3).
See [Number conversion](../../features/types/number_handling.md#number-conversion)
for more information.
!!! note "Booleans as numbers"
A JSON boolean converts to `#!cpp 0` or `#!cpp 1` for every arithmetic type **except** [`number_integer_t`](number_integer_t.md),
[`number_unsigned_t`](number_unsigned_t.md) and [`number_float_t`](number_float_t.md) (by default `#!cpp std::int64_t`,
`#!cpp std::uint64_t`, and `#!cpp double`), for which `#!cpp get<T>()` throws
[`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) ("type must be number, but is boolean"). So
`#!cpp json(true).get<int>()` is `#!cpp 1`, while `#!cpp json(true).get<std::int64_t>()` and
`#!cpp json(true).get<double>()` throw. This is the behavior of all 3.x versions;
[`basic_json_view::get<T>()`](../basic_json_view/get.md) behaves the same.
!!! note "`std::optional` conversions"
Prior to version 3.13.0, `#!cpp get<std::optional<T>>()` (and other conversions to `std::optional<T>`) failed to
@@ -178,13 +188,14 @@ overload (3).
## See also
- [get_to](get_to.md) convert and write into a passed value
- [get_ptr](get_ptr.md) get a pointer to the stored value
- [get_ref](get_ref.md) get a reference to the stored value
- [operator ValueType](operator_ValueType.md) get a value via implicit conversion
- [`get_to`](get_to.md) - convert and write into a passed value
- [`get_ptr`](get_ptr.md) - get a pointer to the stored value
- [`get_ref`](get_ref.md) - get a reference to the stored value
- [`operator ValueType`](operator_ValueType.md) - get a value via implicit conversion
- [Converting values](../../features/conversions.md) - the type conversions article
- [basic_json_view::get](../basic_json_view/get.md) - the same conversion on a zero-copy view (many types are
- [`basic_json_view::get`](../basic_json_view/get.md) - the same conversion on a zero-copy view (many types are
converted without ever building a `basic_json` value)
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) - make your own types usable with `get`
## Version history
@@ -36,7 +36,7 @@ Constant.
## See also
- [basic_json](index.md#template-parameters) the class template, with `AllocatorType` as one of its template parameters
- [`basic_json`](index.md#template-parameters) - the class template, with `AllocatorType` as one of its template parameters
- [Template Parameter Requirements](../../features/types/template_parameters.md#allocatortype) - the requirements for `AllocatorType`
## Version history
@@ -42,8 +42,11 @@ Constant.
## See also
- [get](get.md) get a value (explicit conversion)
- [get_ref](get_ref.md) get a reference to the stored value
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [`binary`](binary.md) - create a binary value
- [`is_binary`](is_binary.md) - check whether a value is binary
- [`get`](get.md) - get a value (explicit conversion)
- [`get_ref`](get_ref.md) - get a reference to the stored value
## Version history
+2 -1
View File
@@ -86,7 +86,8 @@ Constant.
## See also
- [get_ref()](get_ref.md) get a reference value
- [`get_ref()`](get_ref.md) - get a reference value
- [Converting values](../../features/conversions.md) - getting values out, with or without copying
## Version history
+3 -2
View File
@@ -60,9 +60,10 @@ Constant.
## See also
- [get_ptr()](get_ptr.md) get a pointer value
- [basic_json_view::get_string](../basic_json_view/get_string.md) - the closest counterpart on a zero-copy view: a
- [`get_ptr()`](get_ptr.md) - get a pointer value
- [`basic_json_view::get_string`](../basic_json_view/get_string.md) - the closest counterpart on a zero-copy view: a
string without a copy, but as a view rather than a reference to a value that must already exist
- [Converting values](../../features/conversions.md) - getting values out, with or without copying
## Version history
+5 -4
View File
@@ -68,11 +68,12 @@ Depends on the `json_serializer<ValueType>::from_json()` implementation.
## See also
- [get](get.md) get a value (explicit conversion)
- [get_ref](get_ref.md) get a reference to the stored value
- [get_ptr](get_ptr.md) get a pointer to the stored value
- [`get`](get.md) - get a value (explicit conversion)
- [`get_ref`](get_ref.md) - get a reference to the stored value
- [`get_ptr`](get_ptr.md) - get a pointer to the stored value
- [Converting values](../../features/conversions.md) - the type conversions article
- [basic_json_view::get_to](../basic_json_view/get_to.md) - the same conversion on a zero-copy view
- [`basic_json_view::get_to`](../basic_json_view/get_to.md) - the same conversion on a zero-copy view
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) - make your own types usable with `get_to`
## Version history
+9 -4
View File
@@ -189,7 +189,7 @@ The class satisfies the following concept requirements:
Functions to inspect the type of a JSON value.
- [**type**](type.md) - return the type of the JSON value
- [**operator value_t**](operator_value_t.md) - return the type of the JSON value
- [`operator value_t`](operator_value_t.md) - return the type of the JSON value
- [**type_name**](type_name.md) - return the type as string
- [**is_primitive**](is_primitive.md) - return whether the type is primitive
- [**is_structured**](is_structured.md) - return whether the type is structured
@@ -218,7 +218,7 @@ Direct access to the stored value of a JSON value.
- [**get_to**](get_to.md) - get a value and write it to a destination
- [**get_ptr**](get_ptr.md) - get a pointer value
- [**get_ref**](get_ref.md) - get a reference value
- [**operator ValueType**](operator_ValueType.md) - get a value
- [`operator ValueType`](operator_ValueType.md) - get a value
- [**get_binary**](get_binary.md) - get a binary value
- [**as_base_class**](as_base_class.md) - access the custom base class
@@ -359,10 +359,15 @@ Access to the JSON value
## See also
- [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259)
- [basic_json_document](../basic_json_document/index.md) / [basic_json_view](../basic_json_view/index.md) - parse a JSON
- [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259) -
specification of the JSON data interchange format
- [`basic_json_document`](../basic_json_document/index.md) - / [`basic_json_view`](../basic_json_view/index.md) - parse a JSON
text into a flat index and read it through a view
- [Zero-copy JSON views](../../features/json_view.md) - when to use a document and a view instead of a `basic_json`
- [Types](../../features/types/index.md) - how JSON values are stored and which types exist
- [Converting values](../../features/conversions.md) - get values out of a JSON value and put values in
- [Creating JSON values](../../features/creating_values.md) - all the ways to build a JSON value
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) - convert your own types to and from JSON
## Version history
@@ -53,8 +53,9 @@ bon8
## See also
- [sax_parse](sax_parse.md) generic SAX parse interface, taking an `input_format_t` to select the input format
- [cbor_tag_handler_t](cbor_tag_handler_t.md) configures how CBOR tags are treated while parsing
- [`sax_parse`](sax_parse.md) - generic SAX parse interface, taking an `input_format_t` to select the input format
- [`cbor_tag_handler_t`](cbor_tag_handler_t.md) - configures how CBOR tags are treated while parsing
- [Binary Formats](../../features/binary_formats/index.md) - CBOR, MessagePack, BSON, and other formats
## Version history
+11 -5
View File
@@ -65,7 +65,12 @@ the same index, which is now a different value.
## Exception safety
Strong exception safety: if an exception occurs, the original value stays intact.
Overload (1) gives the strong guarantee: if an exception is thrown, there are no changes in the JSON value.
Overloads (2) to (5) give the basic guarantee: if an exception is thrown while the elements or members are copied
(for example, `std::bad_alloc`), the JSON value may be partially modified, but it stays a valid array or object.
The exceptions listed below are thrown before the JSON value is changed.
## Exceptions
@@ -185,10 +190,11 @@ Strong exception safety: if an exception occurs, the original value stays intact
## See also
- [emplace](emplace.md) add a value to an object
- [emplace_back](emplace_back.md) add a value to an array
- [push_back](push_back.md) add a value to an array/object
- [update](update.md) merges objects
- [`emplace`](emplace.md) - add a value to an object
- [`emplace_back`](emplace_back.md) - add a value to an array
- [`push_back`](push_back.md) - add a value to an array/object
- [`update`](update.md) - merges objects
- [Modifying values](../../features/modifying_values.md) - the article on modifying values
## Version history
@@ -40,6 +40,9 @@ classDiagram
style json_invalid_iterator fill:#CCCCFF
```
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
base class, and the highlighted box is `basic_json::invalid_iterator`.</p>
## Member functions
- **what** - returns explanatory string
@@ -66,12 +69,14 @@ classDiagram
## See also
- [`exception`](exception.md) for the base class of all exceptions thrown by the library
- [List of iterator errors](../../home/exceptions.md#iterator-errors)
- [`parse_error`](parse_error.md) for exceptions indicating a parse error
- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type
- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range
- [`other_error`](other_error.md) for exceptions indicating other library errors
- [`exception`](exception.md) - the base class of all exceptions thrown by the library
- [List of iterator errors](../../home/exceptions.md#iterator-errors) - overview of iterator errors (`invalid_iterator`)
- [`parse_error`](parse_error.md) - exceptions indicating a parse error
- [`type_error`](type_error.md) - exceptions indicating executing a member function with a wrong type
- [`out_of_range`](out_of_range.md) - exceptions indicating access out of the defined range
- [`other_error`](other_error.md) - exceptions indicating other library errors
- [Exceptions](../../home/exceptions.md) - all exceptions and their error codes
- [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) - extended exception messages with the path of the failing value
## Version history
+6 -5
View File
@@ -36,11 +36,12 @@ Constant.
## See also
- [is_object](is_object.md) checks whether the JSON value is an object
- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object)
- [type](type.md) returns the type of the JSON value
- [array_t](array_t.md) the type used to store JSON arrays
- [basic_json_view::is_array](../basic_json_view/is_array.md) - the same check on a zero-copy view
- [`is_object`](is_object.md) - checks whether the JSON value is an object
- [`is_structured`](is_structured.md) - checks whether the JSON value is structured (array or object)
- [`type`](type.md) - returns the type of the JSON value
- [`array_t`](array_t.md) - the type used to store JSON arrays
- [`basic_json_view::is_array`](../basic_json_view/is_array.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
+5 -4
View File
@@ -36,10 +36,11 @@ Constant.
## See also
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive
- [binary_t](binary_t.md) the type used to store binary values
- [get_binary](get_binary.md) returns a reference to the stored binary value
- [basic_json_view::is_binary](../basic_json_view/is_binary.md) - the same check on a zero-copy view
- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled
- [`is_primitive`](is_primitive.md) - checks whether the JSON value is primitive
- [`binary_t`](binary_t.md) - the type used to store binary values
- [`get_binary`](get_binary.md) - returns a reference to the stored binary value
- [`basic_json_view::is_binary`](../basic_json_view/is_binary.md) - the same check on a zero-copy view
## Version history
@@ -36,9 +36,10 @@ Constant.
## See also
- [boolean_t](boolean_t.md) the type used to store JSON booleans
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive
- [basic_json_view::is_boolean](../basic_json_view/is_boolean.md) - the same check on a zero-copy view
- [`boolean_t`](boolean_t.md) - the type used to store JSON booleans
- [`is_primitive`](is_primitive.md) - checks whether the JSON value is primitive
- [`basic_json_view::is_boolean`](../basic_json_view/is_boolean.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
@@ -87,8 +87,9 @@ with `allow_exceptions` set to `#!cpp false`: a parse error then yields a discar
## See also
- [basic_json_view::is_discarded](../basic_json_view/is_discarded.md) - the corresponding check on a zero-copy view,
- [`basic_json_view::is_discarded`](../basic_json_view/is_discarded.md) - the corresponding check on a zero-copy view,
which is `#!cpp true` if the view refers to no value
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
+6 -5
View File
@@ -36,11 +36,12 @@ Constant.
## See also
- [is_array](is_array.md) checks whether the JSON value is an array
- [is_object](is_object.md) checks whether the JSON value is an object
- [type](type.md) returns the type of the JSON value
- [value_t](value_t.md) the enumeration of JSON types
- [basic_json_view::is_null](../basic_json_view/is_null.md) - the same check on a zero-copy view
- [`is_array`](is_array.md) - checks whether the JSON value is an array
- [`is_object`](is_object.md) - checks whether the JSON value is an object
- [`type`](type.md) - returns the type of the JSON value
- [`value_t`](value_t.md) - the enumeration of JSON types
- [`basic_json_view::is_null`](../basic_json_view/is_null.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
+6 -4
View File
@@ -46,10 +46,12 @@ constexpr bool is_number() const noexcept
## See also
- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number
- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number
- [is_number_float()](is_number_float.md) check if the value is a floating-point number
- [basic_json_view::is_number](../basic_json_view/is_number.md) - the same check on a zero-copy view
- [`is_number_integer()`](is_number_integer.md) - check if the value is an integer or unsigned integer number
- [`is_number_unsigned()`](is_number_unsigned.md) - check if the value is an unsigned integer number
- [`is_number_float()`](is_number_float.md) - check if the value is a floating-point number
- [`basic_json_view::is_number`](../basic_json_view/is_number.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted
## Version history
@@ -37,10 +37,12 @@ Constant.
## See also
- [is_number()](is_number.md) check if the value is a number
- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number
- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number
- [basic_json_view::is_number_float](../basic_json_view/is_number_float.md) - the same check on a zero-copy view
- [`is_number()`](is_number.md) - check if the value is a number
- [`is_number_integer()`](is_number_integer.md) - check if the value is an integer or unsigned integer number
- [`is_number_unsigned()`](is_number_unsigned.md) - check if the value is an unsigned integer number
- [`basic_json_view::is_number_float`](../basic_json_view/is_number_float.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted
## Version history
@@ -37,10 +37,12 @@ Constant.
## See also
- [is_number()](is_number.md) check if the value is a number
- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number
- [is_number_float()](is_number_float.md) check if the value is a floating-point number
- [basic_json_view::is_number_integer](../basic_json_view/is_number_integer.md) - the same check on a zero-copy view
- [`is_number()`](is_number.md) - check if the value is a number
- [`is_number_unsigned()`](is_number_unsigned.md) - check if the value is an unsigned integer number
- [`is_number_float()`](is_number_float.md) - check if the value is a floating-point number
- [`basic_json_view::is_number_integer`](../basic_json_view/is_number_integer.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted
## Version history
@@ -40,10 +40,12 @@ Constant.
## See also
- [is_number()](is_number.md) check if the value is a number
- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number
- [is_number_float()](is_number_float.md) check if the value is a floating-point number
- [basic_json_view::is_number_unsigned](../basic_json_view/is_number_unsigned.md) - the same check on a zero-copy view
- [`is_number()`](is_number.md) - check if the value is a number
- [`is_number_integer()`](is_number_integer.md) - check if the value is an integer or unsigned integer number
- [`is_number_float()`](is_number_float.md) - check if the value is a floating-point number
- [`basic_json_view::is_number_unsigned`](../basic_json_view/is_number_unsigned.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted
## Version history
+6 -5
View File
@@ -36,11 +36,12 @@ Constant.
## See also
- [is_array](is_array.md) checks whether the JSON value is an array
- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object)
- [type](type.md) returns the type of the JSON value
- [object_t](object_t.md) the type used to store JSON objects
- [basic_json_view::is_object](../basic_json_view/is_object.md) - the same check on a zero-copy view
- [`is_array`](is_array.md) - checks whether the JSON value is an array
- [`is_structured`](is_structured.md) - checks whether the JSON value is structured (array or object)
- [`type`](type.md) - returns the type of the JSON value
- [`object_t`](object_t.md) - the type used to store JSON objects
- [`basic_json_view::is_object`](../basic_json_view/is_object.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
@@ -56,13 +56,14 @@ This library extends primitive types to binary types, because binary types are r
## See also
- [is_structured()](is_structured.md) returns whether the JSON value is structured
- [is_null()](is_null.md) returns whether the JSON value is `null`
- [is_string()](is_string.md) returns whether the JSON value is a string
- [is_boolean()](is_boolean.md) returns whether the JSON value is a boolean
- [is_number()](is_number.md) returns whether the JSON value is a number
- [is_binary()](is_binary.md) returns whether the JSON value is a binary array
- [basic_json_view::is_primitive](../basic_json_view/is_primitive.md) - the same check on a zero-copy view
- [`is_structured()`](is_structured.md) - returns whether the JSON value is structured
- [`is_null()`](is_null.md) - returns whether the JSON value is `null`
- [`is_string()`](is_string.md) - returns whether the JSON value is a string
- [`is_boolean()`](is_boolean.md) - returns whether the JSON value is a boolean
- [`is_number()`](is_number.md) - returns whether the JSON value is a number
- [`is_binary()`](is_binary.md) - returns whether the JSON value is a binary array
- [`basic_json_view::is_primitive`](../basic_json_view/is_primitive.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
+5 -4
View File
@@ -36,10 +36,11 @@ Constant.
## See also
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive
- [type](type.md) returns the type of the JSON value
- [string_t](string_t.md) the type used to store JSON strings
- [basic_json_view::is_string](../basic_json_view/is_string.md) - the same check on a zero-copy view
- [`is_primitive`](is_primitive.md) - checks whether the JSON value is primitive
- [`type`](type.md) - returns the type of the JSON value
- [`string_t`](string_t.md) - the type used to store JSON strings
- [`basic_json_view::is_string`](../basic_json_view/is_string.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
@@ -54,10 +54,11 @@ Note that though strings are containers in C++, they are treated as primitive va
## See also
- [is_primitive()](is_primitive.md) returns whether JSON value is primitive
- [is_array()](is_array.md) returns whether the value is an array
- [is_object()](is_object.md) returns whether the value is an object
- [basic_json_view::is_structured](../basic_json_view/is_structured.md) - the same check on a zero-copy view
- [`is_primitive()`](is_primitive.md) - returns whether JSON value is primitive
- [`is_array()`](is_array.md) - returns whether the value is an array
- [`is_object()`](is_object.md) - returns whether the value is an object
- [`basic_json_view::is_structured`](../basic_json_view/is_structured.md) - the same check on a zero-copy view
- [Types](../../features/types/index.md) - the JSON value types and how they are stored
## Version history
+5 -4
View File
@@ -54,7 +54,7 @@ using element_type = decltype(*j_object.items().begin());
```
The per-element type (`iteration_proxy_value`) lives in the library's internal `detail` namespace and is
intentionally unspecified as a stable, named type -- `decltype` is the supported way to obtain it, but its exact
intentionally unspecified as a stable, named type — `decltype` is the supported way to obtain it, but its exact
name/definition may change between versions.
## Return value
@@ -97,10 +97,11 @@ When iterating over an array, `key()` will return the index of the element as st
## See also
- [begin](begin.md) returns an iterator to the first element
- [end](end.md) returns an iterator to one past the last element
- [basic_json_view::items](../basic_json_view/items.md) - the same range on a zero-copy view (`#!cpp const auto`,
- [`begin`](begin.md) - returns an iterator to the first element
- [`end`](end.md) - returns an iterator to one past the last element
- [`basic_json_view::items`](../basic_json_view/items.md) - the same range on a zero-copy view (`#!cpp const auto`,
not `#!cpp const auto&`: items are produced on the fly; document order, not sorted; duplicate keys are visited)
- [Iterators](../../features/iterators.md#access-object-keys-during-iteration) - the article on iterating over keys and values
## Version history
@@ -57,7 +57,7 @@ same name. Hidden members remain accessible via [`as_base_class`](as_base_class.
## See also
- [as_base_class](as_base_class.md) - access the custom base class
- [`as_base_class`](as_base_class.md) - access the custom base class
- [Template Parameter Requirements](../../features/types/template_parameters.md#custombaseclass) - the requirements for `CustomBaseClass`
## Version history
@@ -44,10 +44,11 @@ deserializes. See [Template Parameter Requirements](../../features/types/templat
## See also
- [adl_serializer](../adl_serializer/index.md) the default `json_serializer`
- [get](get.md) explicit type conversion using the `json_serializer`'s `from_json()` method
- [get_to](get_to.md) explicit type conversion into a variable using the `json_serializer`'s `from_json()` method
- [`adl_serializer`](../adl_serializer/index.md) - the default `json_serializer`
- [`get`](get.md) - explicit type conversion using the `json_serializer`'s `from_json()` method
- [`get_to`](get_to.md) - explicit type conversion into a variable using the `json_serializer`'s `from_json()` method
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) - the article on converting between JSON values and arbitrary types
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `JSONSerializer` template parameter
## Version history
+4 -4
View File
@@ -33,7 +33,7 @@ constant complexity.
## Notes
This function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of
This function does not return the maximal length of a string stored as JSON value — it returns the maximal number of
string elements the JSON value can store which is `1`.
## Examples
@@ -56,9 +56,9 @@ string elements the JSON value can store which is `1`.
## See also
- [size](size.md) returns the number of elements
- [array_t](array_t.md) the type used to store JSON arrays
- [object_t](object_t.md) the type used to store JSON objects
- [`size`](size.md) - returns the number of elements
- [`array_t`](array_t.md) - the type used to store JSON arrays
- [`object_t`](object_t.md) - the type used to store JSON objects
## Version history
@@ -70,9 +70,10 @@ object operation (looking up a key, or adding one to the patch): logarithmic for
## See also
- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
- [merge_patch](merge_patch.md) applies a JSON Merge Patch
- [diff](diff.md) creates a diff as a JSON Patch
- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - specification of JSON Merge Patch
- [`merge_patch`](merge_patch.md) - applies a JSON Merge Patch
- [`diff`](diff.md) - creates a diff as a JSON Patch
- [JSON Merge Patch](../../features/merge_patch.md) - the article on JSON Merge Patch
## Version history
@@ -85,9 +85,10 @@ cost also includes one copy of `apply_patch` (see the notes below).
## See also
- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
- [patch](patch.md) apply a JSON patch
- [merge_diff](merge_diff.md) creates a diff as a JSON Merge Patch
- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - specification of JSON Merge Patch
- [`patch`](patch.md) - apply a JSON patch
- [`merge_diff`](merge_diff.md) - creates a diff as a JSON Merge Patch
- [JSON Merge Patch](../../features/merge_patch.md) - the article on JSON Merge Patch
## Version history
+5 -2
View File
@@ -48,8 +48,11 @@ Constant.
## See also
- [**NLOHMANN_JSON_VERSION_MAJOR**/**NLOHMANN_JSON_VERSION_MINOR**/**NLOHMANN_JSON_VERSION_PATCH**](../macros/nlohmann_json_version_major.md)
\- library version information
- [`NLOHMANN_JSON_VERSION_MAJOR`](../macros/nlohmann_json_version_major.md) /
[`NLOHMANN_JSON_VERSION_MINOR`](../macros/nlohmann_json_version_major.md) /
[`NLOHMANN_JSON_VERSION_PATCH`](../macros/nlohmann_json_version_major.md) - library version information
- [Integration](../../integration/index.md) - integrate the library
- [Supported Macros](../../features/macros.md) - guide to all supported macros
## Version history
@@ -84,10 +84,11 @@ Floating-point number values are stored directly inside a `basic_json` type.
## See also
- [number_integer_t](number_integer_t.md) the type used to store JSON integer numbers
- [number_unsigned_t](number_unsigned_t.md) the type used to store JSON unsigned integer numbers
- [is_number_float](is_number_float.md) checks whether the JSON value is a floating-point number
- [`number_integer_t`](number_integer_t.md) - the type used to store JSON integer numbers
- [`number_unsigned_t`](number_unsigned_t.md) - the type used to store JSON unsigned integer numbers
- [`is_number_float`](is_number_float.md) - checks whether the JSON value is a floating-point number
- [Number Handling](../../features/types/number_handling.md) - the article on number handling
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the number template parameters
## Version history
@@ -80,10 +80,11 @@ Integer number values are stored directly inside a `basic_json` type.
## See also
- [number_unsigned_t](number_unsigned_t.md) the type used to store JSON unsigned integer numbers
- [number_float_t](number_float_t.md) the type used to store JSON floating-point numbers
- [is_number_integer](is_number_integer.md) checks whether the JSON value is a signed integer number
- [`number_unsigned_t`](number_unsigned_t.md) - the type used to store JSON unsigned integer numbers
- [`number_float_t`](number_float_t.md) - the type used to store JSON floating-point numbers
- [`is_number_integer`](is_number_integer.md) - checks whether the JSON value is a signed integer number
- [Number Handling](../../features/types/number_handling.md) - the article on number handling
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the number template parameters
## Version history
@@ -82,10 +82,11 @@ Integer number values are stored directly inside a `basic_json` type.
## See also
- [number_integer_t](number_integer_t.md) the type used to store JSON integer numbers
- [number_float_t](number_float_t.md) the type used to store JSON floating-point numbers
- [is_number_unsigned](is_number_unsigned.md) checks whether the JSON value is an unsigned integer number
- [`number_integer_t`](number_integer_t.md) - the type used to store JSON integer numbers
- [`number_float_t`](number_float_t.md) - the type used to store JSON floating-point numbers
- [`is_number_unsigned`](is_number_unsigned.md) - checks whether the JSON value is an unsigned integer number
- [Number Handling](../../features/types/number_handling.md) - the article on number handling
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the number template parameters
## Version history
@@ -27,8 +27,10 @@ and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise.
## See also
- [object_t](object_t.md) the type used to store JSON objects
- [default_object_comparator_t](default_object_comparator_t.md) the fallback comparator used when `object_t` has no `key_compare` member type
- [`object_t`](object_t.md) - the type used to store JSON objects
- [`default_object_comparator_t`](default_object_comparator_t.md) - the fallback comparator used when `object_t` has no `key_compare` member type
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `ObjectType` template parameter
- [Object order](../../features/object_order.md) - preserve the insertion order of keys
## Version history
+6 -4
View File
@@ -20,7 +20,7 @@ To store objects in C++, a type is defined by the template parameters described
`ObjectType`
: the container to store objects. Its template parameters must have the same order and meaning as those of
`std::map`; in particular, the third parameter is a comparator. `#!cpp std::unordered_map`, whose third parameter
is a hash function, therefore needs an adapter -- see
is a hash function, therefore needs an adapter — see
[Template Parameter Requirements](../../features/types/template_parameters.md#objecttype) for the full list of
requirements, an adapter example, and the containers that are known to work.
@@ -125,10 +125,12 @@ the object is silently converted as an array of key-value pairs, which is incorr
## See also
- [array_t](array_t.md) the type used to store JSON arrays
- [string_t](string_t.md) the type used to store JSON strings
- [object_comparator_t](object_comparator_t.md) the comparator used to order object keys
- [`array_t`](array_t.md) - the type used to store JSON arrays
- [`string_t`](string_t.md) - the type used to store JSON strings
- [`object_comparator_t`](object_comparator_t.md) - the comparator used to order object keys
- [Object Order](../../features/object_order.md) - the article on object key ordering
- [Types](../../features/types/index.md) - how objects are stored
- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `ObjectType` template parameter
## Version history
@@ -123,8 +123,9 @@ interpreted as `object_t::value_type` or `std::initializer_list<basic_json>`, se
## See also
- [emplace_back](emplace_back.md) add a value to an array
- [push_back](push_back.md) add a value to an array/object
- [`emplace_back`](emplace_back.md) - add a value to an array
- [`push_back`](push_back.md) - add a value to an array/object
- [Modifying values](../../features/modifying_values.md) - the article on modifying values
## Version history
+3 -2
View File
@@ -45,8 +45,9 @@ Linear.
## See also
- [basic_json](basic_json.md) create a JSON value
- [swap](swap.md) exchanges the contents of two JSON values
- [`basic_json`](basic_json.md) - create a JSON value
- [`swap`](swap.md) - exchanges the contents of two JSON values
- [Creating JSON values](../../features/creating_values.md) - ways to create and assign JSON values
## Version history
+27 -7
View File
@@ -92,12 +92,20 @@ Strong exception safety: if an exception occurs, the original value stays intact
For the **const** version, an object key or array index in `ptr` that does not exist is not reported by an
exception, but is undefined behavior (see the notes below). Use [`at`](at.md) for checked access.
If the **non-const** version throws, the value is left unchanged: values it created for earlier reference tokens
of `ptr` are removed again. This also holds for exceptions such as `#!cpp std::bad_alloc` or
`#!cpp std::length_error` thrown while padding an array up to a very large index. With custom
[template parameters](../../features/types/template_parameters.md), this requires that `erase()` of the object and
array types and the move operations of the custom base class do not throw.
## Complexity
1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`.
2. Logarithmic in the size of the container.
3. Logarithmic in the size of the container.
4. Logarithmic in the size of the container.
4. Linear in the number of reference tokens of `ptr`; for each of them, logarithmic in the size of the object, or
constant for an array. When the non-const version pads an array with `#!json null` values, it is additionally
linear in `idx - size()` for that array.
## Notes
@@ -145,6 +153,14 @@ Strong exception safety: if an exception occurs, the original value stays intact
specified by the JSON Pointer RFC; it is this library's own, intentional disambiguation rule. See also
[JSON Pointer](../../features/json_pointer.md).
!!! warning "Large array indices"
As the array is filled up with `#!json null` values to the given index, the memory used grows with the index
and not with the size of the pointer: on a 64-bit platform, the index `10000000` allocates about 160 MB.
The library does not limit the index, so check the array indices of a JSON pointer from untrusted input
before using it with the non-const version. See
[Parsing untrusted input](../../features/parsing/untrusted_input.md#json-pointers-and-flattened-keys).
!!! warning "Deprecation"
Overload (4) also accepts a [`json_pointer`](../json_pointer/index.md) whose template argument is a `basic_json`
@@ -274,13 +290,15 @@ Strong exception safety: if an exception occurs, the original value stays intact
## See also
- documentation on [unchecked access](../../features/element_access/unchecked_access.md)
- documentation on [runtime assertions](../../features/assertions.md)
- see [`at`](at.md) for access by reference with range checking
- see [`value`](value.md) for access with default value
- [basic_json_view::operator[]](../basic_json_view/operator%5B%5D.md) - the same access on a zero-copy view (a duplicate
- [Unchecked access](../../features/element_access/unchecked_access.md) - element access without range checking
- [Runtime assertions](../../features/assertions.md) - assertions guarding against undefined behavior
- [`at`](at.md) - access by reference with range checking
- [`value`](value.md) - access with default value
- [`basic_json_view::operator[]`](../basic_json_view/operator%5B%5D.md) - the same access on a zero-copy view (a duplicate
key resolves to the first member, whereas `parse()` keeps the last; a missing key gives a discarded view instead of
undefined behavior)
- [Element Access](../../features/element_access/index.md) - overview of all ways to access elements
- [JSON Pointer](../../features/json_pointer.md) - access nested values with a pointer
## Version history
@@ -294,4 +312,6 @@ Strong exception safety: if an exception occurs, the original value stays intact
4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since
version 3.13.0. Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not
a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones.
a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones. Fixed in version 3.13.0 to leave the value
unchanged if the non-const version throws (strong exception safety, as documented); before, values created for earlier
reference tokens of `ptr` were kept.
Loaded 100 of 537 files, more files were not shown because too many files have changed in this diff. Show more