Compare commits

..
Author SHA1 Message Date
Niels Lohmann d60ac0aff1 Merge branch 'develop' into cbor-integer-writer
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:26:44 +02:00
Niels Lohmann b41228c227 Fix AppVeyor failures from the Zmij double writer (#5843)
MSVC 2015 warns C4554 on the shifts with casts in the fractional part
of zmij::to_shortest despite the parentheses; with /WX every target
fails to build. Name the shift amounts as constants instead.

The shortest-digits test built the candidates with one digit fewer via
a stream with std::setprecision(digits.size() - 2); the standard library
of MSVC 2017 ignores a precision of 0, so for two-digit values the
"shorter" candidates were the value itself. Truncate the digits
instead: the value lies within half a unit of the last digit, so the
truncated digits and their successor are the closest candidates.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:08:12 +02:00
Niels Lohmann dcb96e82fb Escape characters below 0x60 from a table straight into the write buffer (#5822)
* Escape characters below 0x60 from a table straight into the write buffer

When the bulk scanner in dump_escaped_impl() stops at a control
character, a quote or a backslash, that byte used to go through the
UTF-8 decoder and a switch that wrote the escape byte by byte into
string_buffer, which was then copied into write_buffer at the next run.

A byte below 0x60 at a character boundary is a complete code point, so
it now skips the decoder: its escape sequence comes from a 96-entry
table of 8-byte rows (sequence padded with zeros, length in the last
byte), and all 8 bytes are copied straight into write_buffer with one
room check. The check sits inside the existing character-boundary
block, so it runs once per scanner stop and not once per byte; testing
every byte cost about 6% on twitter.json with ensure_ascii.

The switch in the decoder's accept branch lost its cases for
characters below 0x60, which can no longer reach it.

Output is byte-identical. The string-buffer boundary tests now use
\u-escaped non-ASCII characters, since simple escapes no longer reach
string_buffer, and a new test case checks every ASCII character at
every position against a reference escaper.

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

* Avoid raw string literals with backslashes in CHECK macros

MSVC's traditional preprocessor mis-lexes raw string literals inside
macro arguments and reports illegal escape sequences (C2017, C3850).

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

* Sweep invalid UTF-8 at every position through dump()

Compare dump() of strings with ill-formed UTF-8 (stray continuation
bytes, invalid lead bytes, overlong encodings, surrogates, code points
above U+10FFFF, and sequences cut short by ASCII, a quote, a backslash,
a lead byte, or the end of the string) with an independent reference
serializer, for every error handler and with ensure_ascii on and off.
The pattern is put at every position of short strings to cross the
strides of the bulk scanners, and of longer ones to cross the end of the
512-byte string buffer.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:08:10 +02:00
dependabot[bot] c7fd5ac19f Bump the codeql-action group with 4 updates (#5846)
Bumps the codeql-action group with 4 updates: [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.38.2 to 4.38.3
- [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/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d)

Updates `github/codeql-action/autobuild` from 4.38.2 to 4.38.3
- [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/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d)

Updates `github/codeql-action/analyze` from 4.38.2 to 4.38.3
- [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/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d)

Updates `github/codeql-action/upload-sarif` from 4.38.2 to 4.38.3
- [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/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.38.3
  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-15 20:05:49 +02:00
dependabot[bot] a678aa6dd7 Bump actions/setup-node from 7.0.0 to 7.1.0 (#5847)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 7.0.0 to 7.1.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/820762786026740c76f36085b0efc47a31fe5020...949feb2413d6458794dcd2491c4babbbce0c15c1)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 7.1.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-10-15 20:05:39 +02:00
dependabot[bot] 3d93f682a7 Bump step-security/harden-runner from 2.22.0 to 2.22.1 (#5848)
Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.22.0 to 2.22.1.
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/351661ca32ac09a36dc5ee2d536e3128f2a3c8ed...ccd8616d44fd3846e67624a50d5aad6d37bf2d25)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.22.1
  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-15 20:05:28 +02:00
dependabot[bot] 1c696dcf05 Bump actions/upload-artifact from 7.0.1 to 7.0.2 (#5849)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a...cf430e030ddbb5b0abf93d22962f4752f3646cd9)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.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-15 20:05:17 +02:00
dependabot[bot] 7cd34c62a9 Bump lukka/get-cmake from 4.4.2 to 4.4.4 (#5819)
Bumps [lukka/get-cmake](https://github.com/lukka/get-cmake) from 4.4.2 to 4.4.4.
- [Release notes](https://github.com/lukka/get-cmake/releases)
- [Changelog](https://github.com/lukka/get-cmake/blob/main/RELEASE_PROCESS.md)
- [Commits](https://github.com/lukka/get-cmake/compare/fffaaafeea488556c2c12dad60690008bc1caacb...a89e43e22a96abafcd7a62db652a65ecd33052c9)

---
updated-dependencies:
- dependency-name: lukka/get-cmake
  dependency-version: 4.4.4
  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-15 20:05:07 +02:00
Niels Lohmann eb74fe2ab7 Fuzz the streaming input adapters against the contiguous one (#5827)
* Fuzz the streaming input adapters against the contiguous one

The fast paths for contiguous input (bulk string scanning, multi-byte
loads, lazy position tracking) are taken only when parsing from a
pointer range; streams and non-contiguous iterators still read byte by
byte. The fuzzer drivers parsed only contiguous input, so a difference
between the two would ship unnoticed.

check_input_adapters() in fuzzer_common.hpp reads the input through a
std::istringstream, a std::list iterator range, and (on POSIX) a FILE*
from fmemopen, and asserts the same value, or the same exception id,
message and byte position, as for the pointer range. All seven drivers
call it; the JSON driver checks parse and accept, each with and without
ignore_comments. It replaces the stream check of the BON8 driver.

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

* Rename the reader parameter to avoid a flawfinder false positive

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:04:57 +02:00
Niels Lohmann 91b9ee2602 Update cppcheck to 1.5.2 (Cppcheck 2.20) and fix its new findings (#5829)
Cppcheck 2.20 rejects invocations of unknown function-like macros in #if
conditions instead of evaluating them as 0. default_defines.hpp expands
the Hedley macros to the compiler's feature-test operators (__has_attribute
etc.), so define them as 0 in a generated include file.

It also reports a false bufferAccessOutOfBounds in the float overload of
float_from_bits, sizing the parameter as the double overload's; use the
size of the source instead (equal by the static_assert).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:04:46 +02:00
Niels Lohmann ce28c722bc Allow the same type for number_integer_t and number_unsigned_t (#5815)
* Allow the same type for number_integer_t and number_unsigned_t

basic_json did not compile with NumberUnsignedType == NumberIntegerType
because overloads on both types collided. Such a basic_json now stores
every integer as number_integer: the colliding overloads take a
placeholder type, unsigned C++ integers are converted to number_integer_t,
and value_t::number_unsigned maps to number_integer.

Also fixes two problems this configuration would hit: the unsigned
integer parser accepted values that wrap around to negative numbers, and
dump() overflowed when computing the absolute value of the minimum.

A repeated NumberFloatType gets a static_assert.

Refs #2573

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

* Use json::with_integers_t in the test and the docs

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

* ✅ skip patch test on GCC 5 to avoid internal compiler error

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

* Fix CI: name the unsigned overload type through template parameters

basic_json used number_unsigned_overload_t<basic_json> while the class was
still incomplete. MSVC rejected it as a recursive alias declaration and GCC
4.9, 5 and 7 crashed with an internal compiler error. basic_json now uses
number_unsigned_overload_type<NumberIntegerType, NumberUnsignedType>, which
also makes the GCC 5 workaround in the patch test unnecessary.

Infer reported a null dereference for the number_unsigned case in
from_json, which cannot happen for a basic_json whose number_unsigned_t is
number_integer_t; assert it.

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

* Address review: conjunction/negation trait, astyle-friendly alias, docs table order

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:04:42 +02:00
Niels Lohmann 6261d1e432 Construct the JSON Patch exceptions out of line (#5842)
patch_inplace() built its error messages inline. In particular get_value()
concatenated the context-sensitive "operation 'x'" string on every call, even
when nothing was wrong. The patch exceptions now come from NEVER_INLINE
helpers: the index and key errors reuse basic_json's existing
throw_array_index_out_of_range/throw_key_not_found, and the seven
patch-specific messages get one helper each in detail/exceptions.hpp. Ids
and messages are unchanged, and unit-throw_messages pins them (with and
without JSON_DIAGNOSTICS).

citm_catalog patch: -6.6 % (Apple clang), -9.5 % (GCC 16).
The other remaining throw sites (parser::syntax_error, binary_writer,
serializer, input_adapters, enum_key_duplicate, format_error) were prototyped
and measured: no gain beyond noise, so they stay as they are.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:23 +02:00
Niels Lohmann ed86019a21 Move binary reader error construction out of line (#5839)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:23 +02:00
Niels Lohmann 4f11512641 Speed up container destruction, iterator access and diff() (#5835)
* Speed up container destruction, iterator access and diff()

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

* Destroy the first levels of a value by recursion

The pointer-reversing walk in destroy_container() avoids the call stack but
moves a value around for every container it visits. Recurse for the first
recursion_depth_limit() levels instead - no allocation, no thread-local, a
bounded frame - and hand anything deeper to the walk. Destroy twitter
0.49 -> 0.36 ms, citm 0.80 -> 0.74 ms (3.12.0: 0.47 / 1.00).

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:22 +02:00
Niels Lohmann 6a27b9acb2 Construct remaining hot-path exceptions out of line so core functions inline (#5838)
* Construct remaining hot-path exceptions out of line so core functions inline

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

* Move throw_key_not_found() before at_impl()'s comment block

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:22 +02:00
Niels Lohmann 91869983a0 Make the value lifecycle inline-friendly (#5840)
* Make the value lifecycle inline-friendly

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

* Compare standard containers without a thread-local depth count

operator== on objects and arrays recursed through the containers' own
operator== and counted the depth in a thread-local variable. Where reading a
thread-local costs a call (macOS), that added about 10% to comparing documents
with many small containers. For the standard containers, walk objects and
arrays directly, compare scalars and strings inline, and pass the depth as an
argument, falling back to compare_iteratively beyond the depth limit. Other
container types keep the previous path.

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

* Address review: owns_memory() helper, leaf compare naming, astyle

- Add detail::owns_memory(value_t), a switch listing every enumerator so
  -Wswitch-enum flags it when a type is added; destroy() and the copy
  constructor use it instead of hand-written comparisons. Clang emits the
  same bitmask test as before.
- Drop the parentheses around the scalar operands in
  JSON_IMPLEMENT_SCALAR_CASES; they are only needed for the container
  operands (#1530), which the comment now says.
- Build equal_bounded_containers from detail::conjunction so astyle no
  longer pads the template brackets.
- Rename equal_scalar() to equal_leaf() and document why it also compares
  strings, unlike JSON_IMPLEMENT_SCALAR_FAST.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:21 +02:00
Niels Lohmann 4530d9681c Fix quadratic parent updates for ordered_json with JSON_DIAGNOSTICS (#5832)
* Fix quadratic parent updates for ordered_json with JSON_DIAGNOSTICS

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

* Only trust containers known to keep their elements in place

Address review: decide whether an insertion may have moved the other
members by naming the containers that are known not to, instead of the
ones that are known to.

- detail::has_stable_elements: std::map, std::multimap,
  std::unordered_map and std::unordered_multimap; object_capacity()
  reports 0 for them.
- detail::is_nlohmann_ordered_map: only the real nlohmann::ordered_map
  (which only appends) reports its capacity().
- Any other object type reports unknown_size(), so it gets a full
  set_parents() on every insertion. Before, an object type without
  capacity() was treated as never moving, and one with capacity() (a
  sorted flat map, say) was trusted to move only on reallocation.
- set_parents_after_object_erase() re-parents unless the object type is
  stable; the unused set_parent() is removed.
- Comments say "the object type" instead of "ordered_json".
- New test with an object type that moves its members without changing
  its capacity; it fails without this change.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:21 +02:00
Niels Lohmann ca7740fef2 Move elements when converting rvalue containers to JSON (#5837)
* Move elements when converting rvalue containers to JSON

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

* Simplify the rvalue to_json traits

Use negation<disjunction<...>> instead of a conjunction of negations and
keep the template argument lists compact (astyle only keeps the spaced
'< ... >' form when it is written that way).

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:20 +02:00
Niels Lohmann 6ba53e63dd Speed up array-to-container from_json (#5833)
* Speed up array-to-container from_json

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

* Hint the end when converting an object to a standard container

from_json for map-like containers called emplace() without a hint, which
searches the tree for every key. The keys of the source object are sorted, so
inserting with the end as the hint is constant time, as it was in 3.12.0 via
std::inserter. get<std::map<...>>() of a 25,000 entry object: 4.2 ms -> 3.25 ms
(3.12.0: 3.7 ms).

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

* Fall back to emplace() in object from_json for containers without emplace_hint()

ordered_map has no hinted insert, so the insert(end(), ...) call broke
from_json into types holding an ordered_map (regression test #5122).
Use emplace_hint() where available and plain emplace() otherwise.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:20 +02:00
Niels Lohmann 0a4b3a84ee Speed up JSON pointer parsing, formatting, comparison and lookup (#5836)
* Speed up JSON pointer parsing, formatting, comparison and lookup

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

* Restore unflatten() speed after the linear-time rewrite

The prefix tree introduced for linear unflatten() kept a std::map per prefix,
copied each token into it and looked every token up a second time while
creating the values. Replace the per-prefix maps by one open-addressing table
keyed by (parent, token) that refers to the parsed tokens, skip the lookups for
the prefix shared with the previous key (flattened objects are mostly sorted),
and derive the prefix numbers of the second pass from parent links instead of
lookups.

Time and memory stay linear in the pointer depth, and the result is still
independent of the iteration order of the flattened object.

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

* Put [[noreturn]] before __attribute__ on the JSON pointer throw helpers

Clang 18 on Linux rejects a C++11 attribute list after a GNU
__attribute__ ("an attribute list cannot appear here").

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:20 +02:00
Niels Lohmann 0c4e7c103c Make flatten() linear for ordered_json (#5834)
* Make flatten() linear for ordered_json

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

* Use priority_tag instead of a C-style variadic overload in add_flattened

clang-tidy flags the ellipsis fallback (cert-dcl50-cpp,
modernize-avoid-variadic-functions).

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:19 +02:00
Niels Lohmann a6e9785ab6 Look up the key only once in the callback parser's key() (#5831)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 20:01:19 +02:00
Niels Lohmann 35d1ec5ece Fix clang-tidy and GCC warnings in the integer array test
Use std::array for the boundary table (modernize-avoid-c-arrays) and drop
the casts to number_integer_t, which is std::int64_t already
(-Wuseless-cast).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-15 13:10:20 +02:00
Niels Lohmann 3aa3d87983 Use std::array for the integer size class table
clang-tidy (cppcoreguidelines-avoid-c-arrays) rejects the C-style array.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-14 19:34:12 +02:00
Niels Lohmann 4e294f4b18 Clarify that double is only the default floating-point type in the docs (#5830)
Follow-up to review comments on #5825: number_float_t uses double
precision only by default, and the stated limits apply to double.
Also say "default type for X_t" instead of "default value for X_t".

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-14 18:28:49 +02:00
Niels Lohmann 5010011656 Write MessagePack integers without branching on their sign or size
Like CBOR before #5824, MessagePack integer arrays were no faster than in
3.12.0: the type switch (number_integer vs. number_unsigned), the sign
test, and the fixint/8/16/32/64-bit ladder mispredict on mixed data.

They now take the CBOR approach:

- number_integer and number_unsigned share one case of write_msgpack.
- The format comes from the size class of x, where x is the value itself
  if it is not negative and 2 * (-1 - n) + 1 for a negative n: n fits
  int 8/16/32 exactly if that fits uint 8/16/32, so one table lookup
  serves both signs. The fixint bound (127, or -32) is selected through a
  mask, and the marker is 0xCB + class for uint and 0xCF + class for int.
- Arrays are written by an out-of-line write_msgpack_array() with runs of
  integers encoded straight into space reserved from the sink.

The CBOR integer code is factored into helpers both formats share
(integer_bits, integer_size_class, encode_first_byte_and_tail,
write_array_elements). The new path picks the format from the low 64
bits, so number types wider than that keep the previous range checks.

The output is unchanged; the integer-array test now also checks
MessagePack against an independent encoder.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-14 14:26:24 +02:00
Niels Lohmann bbb33374d4 Write CBOR integers without branching on their sign or size
The sizes of a run of integers are hard to predict, and so is the type of
each element in an array that mixes negative (number_integer) and
non-negative (number_unsigned) values. Writing an integer branched on the
type, the sign, and the 1/2/4/8-byte size class, and the mispredictions
were the larger part of the time left on integer arrays.

- number_integer and number_unsigned share one case of write_cbor; the
  major type and the argument are selected with a sign mask.
- An integer's head is assembled without branches: the size class comes
  from a table indexed by count_leading_zeros(), and the first byte and
  the argument in network order are stored as one byte and one 8-byte
  word, of which only the head's length is kept. Heads of strings and
  containers keep the branching write_cbor_head(), as their lengths are
  mostly predictable.
- Arrays are written by write_cbor_array(), kept out of line so that the
  registers its loop needs are not saved on every call of write_cbor.
  Runs of integers are encoded straight into space reserved from the sink
  (the new reserve()/commit() of both sinks), so the write pointer stays
  in a register instead of being reloaded for every value.

The output is unchanged; the new test compares integer arrays at every
head-size boundary, in runs shorter and longer than one reservation and
broken up by other values, with an independent encoder through each sink.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-14 13:48:16 +02:00
Niels Lohmann e26e1ad312 Append to the output vector through a position-tracking sink
The vector-returning to_cbor(), to_msgpack(), ... wrote through
output_vector_sink, which appended each write with push_back() or
insert(). A number's 1 to 8 payload bytes went through vector::insert(),
which libc++ and libstdc++ both run as an out-of-line insert-anywhere
routine; on integer arrays that call cost more than encoding the number,
so the devirtualization of #5286 brought nothing there, and with GCC the
writer was slower than in 3.12.0.

output_vector_sink now keeps its own write position: it grows the vector
geometrically ahead of the position (resize(), using any capacity the
vector already has), copies each write there, and shrinks the vector to
the written length in its destructor, also when a write throws. Writes of
256 characters or more that do not fit are appended with insert(), so a
large string or binary value is copied once instead of zero-filled and
copied. The sink is move-only, as it owns that trim.

output_vector_adapter (the to_*(j, vector) overloads) appends with
push_back()/insert() again, so a caller holding the adapter never sees
the space kept ahead.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-14 13:47:36 +02:00
209 changed files with 6902 additions and 11791 deletions

No files matched your search

-17
View File
@@ -56,23 +56,6 @@ labels:
- label: "aspect: binary formats"
title: "(?i)(bson|cbor|msgpack|messagepack|ubjson|bjdata|bon8|binary format)"
- label: "aspect: json_view"
files:
- "include/nlohmann/json_view\\.hpp"
- "include/nlohmann/detail/view/.*"
- "single_include/nlohmann/json_view\\.hpp"
- "tests/src/unit-json_view.*"
- "tests/src/fuzzer-parse_json_view\\.cpp"
- "tools/amalgamate/config_json_view\\.json"
- "docs/mkdocs/docs/features/json_view\\.md"
- "docs/mkdocs/docs/api/basic_json_(document|view)/.*"
- "docs/mkdocs/docs/api/(ordered_)?json_(document|view)\\.md"
- "docs/mkdocs/docs/examples/(basic_json_(document|view)__|(ordered_)?json_(document|view)).*"
- "tests/benchmarks/src/benchmarks_view\\.cpp"
- label: "aspect: json_view"
title: "(?i)(json_view|json_document|zero-copy)"
- label: "python"
files:
- "\\.py$"
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
+5 -8
View File
@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -31,7 +31,7 @@ jobs:
mkdir -p ./pr
echo ${{ github.event.number }} > ./pr/number
echo ${{ github.event.pull_request.user.login }} > ./pr/author
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: pr
path: pr/
@@ -46,7 +46,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -116,15 +116,12 @@ jobs:
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s .
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.json -s .
# the configuration of json_view.hpp comes with the pull request until
# it is on develop; the tool itself is still develop's
python3 $TOOL_DIR/amalgamate.py -c $MAIN_DIR/tools/amalgamate/config_json_view.json -s .
# the header list of the Bazel "json" target must match the files in include/
cmake -P cmake/scripts/gen_bazel_build_file.cmake
${{ github.workspace }}/venv/bin/astyle --project=tools/astyle/.astylerc --suffix=none --quiet \
$INCLUDE_DIR/json.hpp $INCLUDE_DIR/json_fwd.hpp $INCLUDE_DIR/json_view.hpp
$INCLUDE_DIR/json.hpp $INCLUDE_DIR/json_fwd.hpp
# fail loudly if a directory is renamed or removed: find would only warn
# about the missing path and silently drop its files from the check
@@ -173,7 +170,7 @@ jobs:
# instead of installing the pinned astyle version locally.
- name: Upload patch
if: steps.diff.outputs.has_diff == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: amalgamation-patch
path: patch/amalgamation.patch
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -35,7 +35,7 @@ jobs:
dry-run: false
language: c++
- name: Upload Crash
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
+4 -4
View File
@@ -27,7 +27,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -38,14 +38,14 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
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@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
uses: github/codeql-action/autobuild@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
@@ -20,7 +20,7 @@ jobs:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
+2 -2
View File
@@ -31,7 +31,7 @@ jobs:
security-events: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -47,6 +47,6 @@ jobs:
output: 'flawfinder_results.sarif'
- name: Upload analysis results to GitHub Security tab
uses: github/codeql-action/upload-sarif@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
with:
sarif_file: ${{github.workspace}}/flawfinder_results.sarif
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
+3 -3
View File
@@ -40,7 +40,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -72,7 +72,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: SARIF file
path: results.sarif
@@ -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@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
with:
sarif_file: results.sarif
+2 -2
View File
@@ -36,7 +36,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
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@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
with:
sarif_file: semgrep.sarif
if: always()
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
+26 -26
View File
@@ -25,7 +25,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -38,7 +38,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Check that Meson and pkg-config offer the CMake options
run: make check_build_options
- name: Install Meson
@@ -80,7 +80,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -92,14 +92,14 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
run: cmake --build build --target ci_infer
- name: Archive Infer report
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: infer-report
path: ${{ github.workspace }}/build/build_infer/infer-out/report.txt
@@ -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@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -123,7 +123,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -142,7 +142,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -168,7 +168,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -178,7 +178,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -197,7 +197,7 @@ jobs:
- name: Build
run: cmake --build build --target ci_test_coverage
- name: Archive coverage report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: code-coverage-report
path: ${{ github.workspace }}/build/html
@@ -244,7 +244,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: CXX=g++-${{ matrix.compiler }} cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -262,7 +262,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -279,7 +279,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Disable filesystem support (std::filesystem is unusable) for clang 7 / 8 / 9 / 10
run: echo "JSON_FORCED_GLOBAL_COMPILE_OPTIONS=-DJSON_HAS_FILESYSTEM=0;-DJSON_HAS_EXPERIMENTAL_FILESYSTEM=0" >> "$GITHUB_ENV"
if: ${{ matrix.compiler == '7' || matrix.compiler == '8' || matrix.compiler == '9' || matrix.compiler == '10' }}
@@ -299,7 +299,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -319,7 +319,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build with libc++
@@ -346,7 +346,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -366,7 +366,7 @@ jobs:
# import-std support. Its opt-in token is CMake-version-specific, so pin
# CMake to the version whose token is set in tests/module_cpp20/CMakeLists.txt.
- name: Get pinned CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
with:
cmakeVersion: 4.3.4
# Clang: the std library module is provided by libc++ (the image's libstdc++
@@ -392,7 +392,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -409,7 +409,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -423,7 +423,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -433,7 +433,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -443,7 +443,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Run CMake
run: cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -GNinja
- name: Build
@@ -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@351661ca32ac09a36dc5ee2d536e3128f2a3c8ed # v2.22.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit
@@ -465,7 +465,7 @@ jobs:
persist-credentials: false
# the git-revision-date-localized plugin needs the history; a shallow clone makes the strict build fail
fetch-depth: ${{ matrix.target == 'ci_test_build_documentation' && '0' || '1' }}
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
if: matrix.target == 'ci_test_documentation_mermaid'
with:
node-version: 24
@@ -484,7 +484,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Check that the job runs natively on arm64
run: uname -m && test "$(uname -m)" = aarch64
- name: Run CMake
+2 -2
View File
@@ -90,7 +90,7 @@ jobs:
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
- name: Set extra CXX_FLAGS for latest std_version
# /wd5285 silences C5285 emitted by the bundled third-party doctest.h, which
# specializes std::tuple (newly diagnosed by the VS2026 v145 toolset)
@@ -214,7 +214,7 @@ jobs:
# import-std support. Its opt-in token is CMake-version-specific, so pin
# CMake to the version whose token is set in tests/module_cpp20/CMakeLists.txt.
- name: Get pinned CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
uses: lukka/get-cmake@a89e43e22a96abafcd7a62db652a65ecd33052c9 # v4.4.4
with:
cmakeVersion: 4.3.4
# CMAKE_CXX_FLAGS replaces CMake's MSVC defaults (which include /EHsc), and
-14
View File
@@ -20,7 +20,6 @@ cc_library(
hdrs = [
"include/nlohmann/adl_serializer.hpp",
"include/nlohmann/byte_container_with_subtype.hpp",
"include/nlohmann/detail/abi_config.hpp",
"include/nlohmann/detail/abi_macros.hpp",
"include/nlohmann/detail/bit_ops.hpp",
"include/nlohmann/detail/conversions/from_json.hpp",
@@ -67,21 +66,9 @@ cc_library(
"include/nlohmann/detail/string_escape.hpp",
"include/nlohmann/detail/string_utils.hpp",
"include/nlohmann/detail/value_t.hpp",
"include/nlohmann/detail/view/builder.hpp",
"include/nlohmann/detail/view/document_data.hpp",
"include/nlohmann/detail/view/errors.hpp",
"include/nlohmann/detail/view/input.hpp",
"include/nlohmann/detail/view/macro_scope.hpp",
"include/nlohmann/detail/view/macro_unscope.hpp",
"include/nlohmann/detail/view/materialize.hpp",
"include/nlohmann/detail/view/node.hpp",
"include/nlohmann/detail/view/number.hpp",
"include/nlohmann/detail/view/scan.hpp",
"include/nlohmann/detail/view/string_ref.hpp",
"include/nlohmann/json.hpp",
"include/nlohmann/json_fwd.hpp",
"include/nlohmann/json_literals.hpp",
"include/nlohmann/json_view.hpp",
"include/nlohmann/ordered_map.hpp",
"include/nlohmann/thirdparty/hedley/hedley.hpp",
"include/nlohmann/thirdparty/hedley/hedley_undef.hpp",
@@ -96,7 +83,6 @@ cc_library(
"single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp",
"single_include/nlohmann/json_literals.hpp",
"single_include/nlohmann/json_view.hpp",
],
includes = ["single_include"],
visibility = ["//visibility:public"],
+8 -15
View File
@@ -26,7 +26,6 @@ AMALGAMATED_FILE=single_include/nlohmann/json.hpp
AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
# json_literals.hpp only includes <nlohmann/json.hpp>, so it is copied verbatim
AMALGAMATED_LITERALS_FILE=single_include/nlohmann/json_literals.hpp
AMALGAMATED_VIEW_FILE=single_include/nlohmann/json_view.hpp
# the header with the argument-counting macros generated by tools/macro_builder
MACRO_SCOPE_HPP=include/nlohmann/detail/macro_scope.hpp
@@ -38,7 +37,7 @@ MACRO_SCOPE_HPP=include/nlohmann/detail/macro_scope.hpp
# main target
all:
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd,_literals,_view}.hpp from the include/nlohmann sources"
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd,_literals}.hpp from the include/nlohmann sources"
@echo "BUILD.bazel - regenerate the Bazel BUILD file from the include/nlohmann sources"
@echo "ChangeLog.md - generate ChangeLog file"
@echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date"
@@ -97,10 +96,10 @@ install_astyle:
# call the Artistic Style pretty printer on all source files
pretty: install_astyle
$(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE) docs/mkdocs/docs/examples/*.cpp docs/mkdocs/docs/examples/*.hpp
$(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) docs/mkdocs/docs/examples/*.cpp docs/mkdocs/docs/examples/*.hpp
# create single header files and pretty print
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE)
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE)
$(MAKE) pretty
# call the amalgamation tool for json.hpp
@@ -115,10 +114,6 @@ $(AMALGAMATED_FWD_FILE): $(SRCS)
$(AMALGAMATED_LITERALS_FILE): include/nlohmann/json_literals.hpp
cp include/nlohmann/json_literals.hpp $(AMALGAMATED_LITERALS_FILE)
# call the amalgamation tool for json_view.hpp (keeps including json.hpp)
$(AMALGAMATED_VIEW_FILE): $(SRCS)
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_view.json -s . --verbose=yes
NATVIS_VENV=tools/generate_natvis/venv
# regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp
@@ -152,18 +147,18 @@ check_build_options:
check-amalgamation:
@status=0; \
banner() { printf '===================================================================\n %s\n===================================================================\n' "$$1"; }; \
for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE) BUILD.bazel nlohmann_json.natvis; do \
for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel nlohmann_json.natvis; do \
mv "$$FILE" "$$FILE~" || exit 1; \
done; \
$(MAKE) amalgamate || status=1; \
$(MAKE) BUILD.bazel || status=1; \
$(MAKE) natvis || status=1; \
for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE); do \
for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE); do \
diff "$$FILE" "$$FILE~" || { banner "$$FILE is out of date! Amalgamation required! Please read the contribution guidelines in file .github/CONTRIBUTING.md."; status=1; }; \
done; \
diff BUILD.bazel BUILD.bazel~ || { banner "BUILD.bazel is out of date! Please run 'make BUILD.bazel'."; status=1; }; \
diff nlohmann_json.natvis nlohmann_json.natvis~ || { banner "nlohmann_json.natvis is out of date! Please run 'make natvis'."; status=1; }; \
for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE) BUILD.bazel nlohmann_json.natvis; do \
for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel nlohmann_json.natvis; do \
mv "$$FILE~" "$$FILE"; \
done; \
$(MAKE) macro_builder_check || status=1; \
@@ -204,7 +199,7 @@ json.tar.xz:
# We use `-X` to make the resulting ZIP file reproducible, see
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
include.zip: BUILD.bazel
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE) BUILD.bazel MODULE.bazel meson.build meson_options.txt LICENSE.MIT
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel MODULE.bazel meson.build meson_options.txt LICENSE.MIT
# Create the files for a release and add signatures and hashes.
release: include.zip json.tar.xz
@@ -214,13 +209,11 @@ release: include.zip json.tar.xz
gpg --armor --detach-sig $(AMALGAMATED_FILE)
gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE)
gpg --armor --detach-sig $(AMALGAMATED_LITERALS_FILE)
gpg --armor --detach-sig $(AMALGAMATED_VIEW_FILE)
gpg --armor --detach-sig json.tar.xz
cp $(AMALGAMATED_FILE) release_files
cp $(AMALGAMATED_FWD_FILE) release_files
cp $(AMALGAMATED_LITERALS_FILE) release_files
cp $(AMALGAMATED_VIEW_FILE) release_files
mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc $(AMALGAMATED_LITERALS_FILE).asc $(AMALGAMATED_VIEW_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files
mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc $(AMALGAMATED_LITERALS_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files
cd release_files ; shasum -a 256 $$(find . -type f -not -name '*.asc' | sed 's|^\./||' | sort) > hashes.txt
-9
View File
@@ -1202,14 +1202,6 @@ binary.set_subtype(0x10);
auto msgpack = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE
```
### Zero-copy views
Header `<nlohmann/json_view.hpp>` adds `json_document`/`json_view`, a read-only, non-owning way to look at a parsed
JSON text: parsing builds a flat index (16 bytes per value) instead of a tree, strings and numbers stay in the source
text, and `materialize()` builds a `json` value for a subtree only when you actually need one. See
[Zero-copy JSON views](https://json.nlohmann.me/features/json_view/) for the details, including which inputs are
borrowed and which are copied.
## Customers
The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but the result of an internet search. If you know further customers of the library, please let me know, see [contact](#contact).
@@ -1409,7 +1401,6 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I
- 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 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.
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
+11 -7
View File
@@ -407,11 +407,10 @@ list(FILTER INDENT_FILES EXCLUDE REGEX "/tests/thirdparty/|/tests/abi/include/nl
set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann)
set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate)
add_custom_target(ci_test_amalgamation
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~ ${include_dir}/json_view.hpp~
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~
COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~
COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~
COMMAND cp ${include_dir}/json_literals.hpp ${include_dir}/json_literals.hpp~
COMMAND cp ${include_dir}/json_view.hpp ${include_dir}/json_view.hpp~
COMMAND cp ${PROJECT_SOURCE_DIR}/BUILD.bazel ${PROJECT_SOURCE_DIR}/BUILD.bazel~
COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle
@@ -421,20 +420,18 @@ add_custom_target(ci_test_amalgamation
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s .
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s .
COMMAND cp ${PROJECT_SOURCE_DIR}/include/nlohmann/json_literals.hpp ${include_dir}/json_literals.hpp
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_view.json -s .
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp ${include_dir}/json_literals.hpp ${include_dir}/json_view.hpp
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp ${include_dir}/json_literals.hpp
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/scripts/gen_bazel_build_file.cmake
COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp
COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp
COMMAND diff ${include_dir}/json_literals.hpp~ ${include_dir}/json_literals.hpp
COMMAND diff ${include_dir}/json_view.hpp~ ${include_dir}/json_view.hpp
COMMAND diff ${PROJECT_SOURCE_DIR}/BUILD.bazel~ ${PROJECT_SOURCE_DIR}/BUILD.bazel
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES}
COMMAND for FILE in `find . -name '*.orig'`\; do false \; done
COMMAND rm -f ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~ ${include_dir}/json_view.hpp~ ${PROJECT_SOURCE_DIR}/BUILD.bazel~
COMMAND rm -f ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~ ${PROJECT_SOURCE_DIR}/BUILD.bazel~
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Check amalgamation, formatting, and BUILD.bazel"
@@ -488,6 +485,13 @@ add_custom_target(ci_clang_analyze
# Check code with Cppcheck.
###############################################################################
# default_defines.hpp expands the Hedley macros to the compiler's feature-test operators, which Cppcheck does not know.
# Since Cppcheck 2.20, it rejects their invocations in #if conditions instead of evaluating them as 0.
file(WRITE ${CMAKE_BINARY_DIR}/cppcheck_feature_tests.hpp "")
foreach(OPERATOR __has_attribute __has_builtin __has_cpp_attribute __has_declspec_attribute __has_extension __has_feature __has_include __has_warning)
file(APPEND ${CMAKE_BINARY_DIR}/cppcheck_feature_tests.hpp "#define ${OPERATOR}(x) 0\n")
endforeach()
add_custom_target(ci_cppcheck
COMMAND mkdir -p cppcheck
COMMAND clang -dM -E -x c++ -std=c++11 ${CMAKE_SOURCE_DIR}/include/nlohmann/thirdparty/hedley/hedley.hpp > default_defines.hpp 2> /dev/null
@@ -496,7 +500,7 @@ add_custom_target(ci_cppcheck
COMMAND venv_cppcheck/bin/cppcheck --enable=warning --check-level=exhaustive --inline-suppr --inconclusive --force
--std=c++11 ${PROJECT_SOURCE_DIR}/include/nlohmann/json.hpp -I ${CMAKE_SOURCE_DIR}/include
--error-exitcode=1 --relative-paths=${PROJECT_SOURCE_DIR} -j ${N} --include=default_defines.hpp
--cppcheck-build-dir=cppcheck
--include=${CMAKE_BINARY_DIR}/cppcheck_feature_tests.hpp --cppcheck-build-dir=cppcheck
-UJSON_CATCH_USER -UJSON_TRY_USER -UJSON_ASSERT -UJSON_INTERNAL_CATCH -UJSON_THROW
-DJSON_HAS_CPP_11 -UJSON_HAS_CPP_14 -UJSON_HAS_CPP_17 -UJSON_HAS_CPP_20 -UJSON_HAS_THREE_WAY_COMPARISON
COMMENT "Check code with Cppcheck"
-6
View File
@@ -4,11 +4,5 @@
# call converts -1 to size_t, which -fsanitize=integer reports as implicit-integer-sign-change. This is
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119429, not a bug in this library. Only that check and only <format> are
# excluded, so implicit sign changes in the library and the tests are still reported.
#
# libstdc++'s <string_view> compares two views of different lengths through `_S_compare(size_type __n1, size_type
# __n2)`, which stores `__n1 - __n2` in a signed difference_type and clamps it to int. Any comparison with a shorter
# view wraps that subtraction on purpose, and -fsanitize=integer reports it as implicit-integer-sign-change. json_view
# compares keys as string views, so the same check is excluded for <string_view> as well.
[implicit-integer-sign-change]
src:*/include/c++/*/format
src:*/include/c++/*/string_view
+1 -1
View File
@@ -1 +1 @@
cppcheck==1.5.1
cppcheck==1.5.2
-1
View File
@@ -50,7 +50,6 @@ cc_library(
"single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp",
"single_include/nlohmann/json_literals.hpp",
"single_include/nlohmann/json_view.hpp",
],
includes = ["single_include"],
visibility = ["//visibility:public"],
+1 -1
View File
@@ -27,7 +27,7 @@ To store objects in C++, a type is defined by the template parameters explained
### Default type
With the default values for `ArrayType` (`std::vector`) and `AllocatorType` (`std::allocator`), the default value for
With the default values for `ArrayType` (`std::vector`) and `AllocatorType` (`std::allocator`), the default type for
`array_t` is:
```cpp
+11 -1
View File
@@ -68,6 +68,14 @@ basic_json(basic_json&& other) noexcept;
`std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with a `key_type` compatible to `string_t`
and a `value_type` from which a `basic_json` value can be constructed.
- **strings**: `string_t`, string literals, and all compatible string containers can be used.
!!! note "Rvalue containers are moved from"
If `val` is an rvalue of a compatible array-like or object-like container other than `array_t`/`object_t`
(e.g., `json j = std::move(vec);` or `json j(std::vector<std::string>{...});`), the elements are moved into
the JSON value instead of copied. Afterwards, the elements of the source container are in a valid but
unspecified state (**moved-from**). Keys of associative containers are `const` and therefore still copied.
Lvalues and `const` rvalues are copied, and the source is left unchanged.
- **numbers**: [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md),
[`number_float_t`](number_float_t.md), and all convertible number types such as `int`, `size_t`, `int64_t`, `float`
or `double` can be used.
@@ -236,7 +244,9 @@ basic_json(basic_json&& other) noexcept;
2. No-throw guarantee: this constructor never throws exceptions.
3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no
`to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any
JSON value.
JSON value. **Exception:** when `val` is an rvalue array-like or object-like container, its elements are moved one
by one; if an exception is thrown in the middle of the conversion (e.g., an allocation failure), the JSON value is
unchanged, but the source container may be left partially moved-from.
4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no
`to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any
JSON value.
+1 -1
View File
@@ -23,7 +23,7 @@ To store boolean values in C++, a type is defined by the template parameter `Bo
### Default type
With the default values for `BooleanType` (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`.
With the default values for `BooleanType` (`#!cpp bool`), the default type for `boolean_t` is `#!cpp bool`.
### Storage
-1
View File
@@ -64,7 +64,6 @@ itself is empty which is `#!cpp false` in the case of a string.
- [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
@@ -40,7 +40,6 @@ Constant.
- [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
## Version history
@@ -39,7 +39,6 @@ Constant.
- [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
@@ -38,7 +38,6 @@ Constant.
- [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
## Version history
@@ -85,11 +85,6 @@ with `allow_exceptions` set to `#!cpp false`: a parse error then yields a discar
--8<-- "examples/is_discarded__parse.output"
```
## See also
- [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
## Version history
- Added in version 1.0.0.
@@ -40,7 +40,6 @@ Constant.
- [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
## Version history
@@ -49,7 +49,6 @@ constexpr bool is_number() const noexcept
- [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
## Version history
@@ -40,7 +40,6 @@ Constant.
- [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
## Version history
@@ -40,7 +40,6 @@ Constant.
- [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
## Version history
@@ -6,6 +6,9 @@ constexpr bool is_number_unsigned() const noexcept;
This function returns `#!cpp true` if and only if the JSON value is an unsigned integer number. This excludes
floating-point and signed integer values.
If [`number_unsigned_t`](number_unsigned_t.md) is the same type as [`number_integer_t`](number_integer_t.md), every
integer is stored as `number_integer_t`, and this function always returns `#!cpp false`.
## Return value
@@ -40,7 +43,6 @@ Constant.
- [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
## Version history
@@ -40,7 +40,6 @@ Constant.
- [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
## Version history
@@ -62,7 +62,6 @@ This library extends primitive types to binary types, because binary types are r
- [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
## Version history
@@ -39,7 +39,6 @@ Constant.
- [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
## Version history
@@ -57,7 +57,6 @@ Note that though strings are containers in C++, they are treated as primitive va
- [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
## Version history
@@ -35,7 +35,7 @@ type to use.
### Default type
With the default values for `NumberFloatType` (`double`), the default value for `number_float_t` is `#!cpp double`.
With the default values for `NumberFloatType` (`double`), the default type for `number_float_t` is `#!cpp double`.
### Default behavior
@@ -52,8 +52,9 @@ With the default values for `NumberFloatType` (`double`), the default value for
> interoperability can be achieved by implementations that expect no more precision or range than these provide, in the
> sense that implementations will approximate JSON numbers within the expected precision.
This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note that
numbers smaller than `-1.79769313486232e+308` or greater than `1.79769313486232e+308` are rejected during parsing with
This implementation does exactly follow this approach, as it uses double precision floating-point numbers by default.
Note that with the default `double`, numbers smaller than `-1.79769313486232e+308` or greater than
`1.79769313486232e+308` are rejected during parsing with
[`out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406). Non-finite values (NaN and infinity) can
only be stored by assigning them directly and are serialized to `null`.
@@ -31,7 +31,7 @@ to use.
### Default type
With the default values for `NumberIntegerType` (`std::int64_t`), the default value for `number_integer_t` is
With the default values for `NumberIntegerType` (`std::int64_t`), the default type for `number_integer_t` is
`#!cpp std::int64_t`.
### Default behavior
@@ -25,14 +25,15 @@ the type to use.
`NumberUnsignedType`
: the type to store unsigned integers. It must be an **unsigned integral** type (`#!cpp std::is_integral`) with a
`#!cpp std::numeric_limits` specialization, and it must be able to represent the absolute value of every
[`number_integer_t`](number_integer_t.md) value. See
[`number_integer_t`](number_integer_t.md) value. Alternatively, it can be the same type as
[`number_integer_t`](number_integer_t.md); then every integer is stored as `number_integer_t`. See
[Template Parameter Requirements](../../features/types/template_parameters.md#numberintegertype-and-numberunsignedtype).
## Notes
### Default type
With the default values for `NumberUnsignedType` (`std::uint64_t`), the default value for `number_unsigned_t` is
With the default values for `NumberUnsignedType` (`std::uint64_t`), the default type for `number_unsigned_t` is
`#!cpp std::uint64_t`.
### Default behavior
@@ -89,3 +90,4 @@ Integer number values are stored directly inside a `basic_json` type.
## Version history
- Added in version 2.0.0.
- Can be the same type as `number_integer_t` since version 3.13.0.
+1 -1
View File
@@ -36,7 +36,7 @@ To store objects in C++, a type is defined by the template parameters described
### Default type
With the default values for `ObjectType` (`std::map`), `StringType` (`std::string`), and `AllocatorType`
(`std::allocator`), the default value for `object_t` is:
(`std::allocator`), the default type for `object_t` is:
```cpp
// until C++14
-1
View File
@@ -55,7 +55,6 @@ JSON value which is `1` in the case of a string.
- [empty](empty.md) checks whether the JSON value has no elements
- [max_size](max_size.md) returns the maximum possible number of elements
- [basic_json_view::size](../basic_json_view/size.md) - the same function on a zero-copy view
## Version history
+1 -1
View File
@@ -32,7 +32,7 @@ JSON class into byte-sized characters during deserialization.
### Default type
With the default values for `StringType` (`std::string`), the default value for `string_t` is `#!cpp std::string`.
With the default values for `StringType` (`std::string`), the default type for `string_t` is `#!cpp std::string`.
### Encoding
-1
View File
@@ -52,7 +52,6 @@ Constant.
- [operator value_t](operator_value_t.md) implicit conversion operator equivalent to this named member function
- [type_name](type_name.md) returns the type as a string, for use in error messages
- [value_t](value_t.md) the enumeration of JSON types
- [basic_json_view::type](../basic_json_view/type.md) - the same function on a zero-copy view
## Version history
@@ -1,72 +0,0 @@
# <small>nlohmann::basic_json_document::</small>accept
```cpp
template<typename InputType>
static bool accept(InputType&& input,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
```
Checks whether the input is valid JSON, accepting and rejecting exactly what
[`BasicJsonType::accept()`](../basic_json/accept.md) does, with the same options. Unlike [`parse()`](parse.md), this
function never throws an exception for invalid input, and the returned `#!cpp bool` is the only result -- no document
is returned.
## Template parameters
`InputType`
: A compatible input; see [`parse`](parse.md#template-parameters).
## Parameters
`input` (in)
: Input to check.
`ignore_comments` (in)
: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
(`#!cpp false`); (optional, `#!cpp false` by default)
`ignore_trailing_commas` (in)
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or
yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default)
## Return value
Whether the input is valid JSON.
## Exception safety
Strong guarantee: this function itself never throws for an invalid input; it can only throw what allocating the
input's own copy (for inputs that are always read into a buffer) throws.
## Complexity
Linear in the length of the input.
## Notes
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp accept(ptr, len)`, does not
compile; see [`parse`](parse.md#notes).
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__accept.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__accept.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
- [`BasicJsonType::accept`](../basic_json/accept.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,58 +0,0 @@
# <small>nlohmann::basic_json_document::</small>basic_json_document
```cpp
// (1)
basic_json_document() = default;
// (2)
basic_json_document(basic_json_document&& other) noexcept = default;
// (3)
basic_json_document(const basic_json_document&) = delete;
```
1. Creates an empty (discarded) document: [`root()`](root.md) returns a discarded view, and
[`is_discarded()`](is_discarded.md) is `#!cpp true`.
2. Move constructor. Takes over `other`'s index and, if owned, its text; `other` is left as an empty document. Views
taken from `other` before the move remain valid, because the index is heap-allocated independently of the
`basic_json_document` object.
3. `basic_json_document` is move-only. Copying is disabled because it would either duplicate a potentially large index
and text, or leave two documents claiming to borrow the same buffer.
## Parameters
`other` (in)
: another document to move the index and text from
## Exception safety
No-throw guarantee: the default and move constructors never throw exceptions.
## Complexity
Constant, for the default and move constructors.
## Examples
??? example
The example below shows the default constructor and demonstrates that `basic_json_document` is move-only.
```cpp
--8<-- "examples/basic_json_document__basic_json_document.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__basic_json_document.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
- [is_discarded](is_discarded.md) - return whether the last parse failed
## Version history
- Added in version 3.13.0.
@@ -1,56 +0,0 @@
# <small>nlohmann::</small>basic_json_document
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
template<typename BasicJsonType>
class basic_json_document;
```
A parsed JSON text, held as a flat index of its values
([16 bytes per value](../../home/architecture.md#node-index-of-json-views)) instead of a tree of `BasicJsonType` values.
Strings and numbers stay in the source text; only strings that contain escapes are decoded, into one buffer owned by
the document. [`basic_json_view`](../basic_json_view/index.md) is a read-only handle to one value of a
`basic_json_document`; [`materialize()`](../basic_json_view/materialize.md) turns a subtree back into the
`BasicJsonType` value that [`BasicJsonType::parse()`](../basic_json/parse.md) would have produced for it.
A document may **borrow** the text it was parsed from (the caller's buffer must then outlive the document) or **own**
it (a copy, or an rvalue `#!cpp std::string` that was moved in); see [`owns_source`](owns_source.md). `basic_json_document`
is move-only: copying a document would either duplicate a potentially large index and text, or leave two documents
claiming to borrow the same buffer, so it is disabled.
## Template parameters
`BasicJsonType`
: a specialization of [`basic_json`](../basic_json/index.md), for instance [`json`](../json.md) or
[`ordered_json`](../ordered_json.md). Only 64-bit `number_integer_t`/`number_unsigned_t` types are supported; this
is checked with a `static_assert`.
## Specializations
- [**json_document**](../json_document.md) - documents of the default specialization [`json`](../json.md)
- [**ordered_json_document**](../ordered_json_document.md) - documents of [`ordered_json`](../ordered_json.md)
## Member types
- **view_type** - the type of view returned by [`root()`](root.md) (`#!cpp basic_json_view<BasicJsonType>`)
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
## Member functions
- [(constructor)](basic_json_document.md)
- [**parse**](parse.md) (_static_) - deserialize from a compatible input, borrowing or owning it as appropriate
- [**parse_copy**](parse_copy.md) (_static_) - deserialize a copy of a compatible input
- [**accept**](accept.md) (_static_) - check whether the input is valid JSON
- [**read**](read.md) - (re-)parse into this document, reusing its memory
- [**root**](root.md) - the view of the root value
- [**is_discarded**](is_discarded.md) - return whether the last parse failed
- [**source**](source.md) - the parsed text
- [**owns_source**](owns_source.md) - return whether the document holds its own copy of the text
- [**node_count**](node_count.md) - the number of index entries (values plus object keys)
- [**memory_usage**](memory_usage.md) - the number of bytes held by the document
- [**shrink_to_fit**](shrink_to_fit.md) - release unused index capacity
## Version history
- Added in version 3.13.0.
@@ -1,49 +0,0 @@
# <small>nlohmann::basic_json_document::</small>is_discarded
```cpp
bool is_discarded() const noexcept;
```
Returns whether the document holds no value, either because it was default-constructed or because the last call to
[`parse()`](parse.md), [`parse_copy()`](parse_copy.md), or [`read()`](read.md) failed with `allow_exceptions` set to
`#!cpp false`.
## Return value
`#!cpp true` if the document is discarded, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
When the document is discarded, [`root()`](root.md) returns a discarded view (its
[`is_discarded()`](../basic_json_view/is_discarded.md) is also `#!cpp true`).
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__is_discarded.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__is_discarded.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
- [is_discarded (basic_json_view)](../basic_json_view/is_discarded.md) - return whether a view is invalid
## Version history
- Added in version 3.13.0.
@@ -1,50 +0,0 @@
# <small>nlohmann::basic_json_document::</small>memory_usage
```cpp
std::size_t memory_usage() const noexcept;
```
Returns the number of bytes held by the document: the node index, the decoded-string buffer (for strings that
contain escapes), and, for an owned document, its copy of the source text.
## Return value
The number of bytes the document holds, `0` for a [discarded](is_discarded.md) document.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
The exact value depends on the platform, the allocator, and the library's own layout, and may change between
versions; do not rely on it being a specific number, and do not compare it across different builds or platforms.
Compare it for the same document over time, or between documents built with the same binary, instead -- for instance
to observe the effect of [`shrink_to_fit()`](shrink_to_fit.md).
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__memory_usage.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__memory_usage.output"
```
## See also
- [node_count](node_count.md) - the number of index entries
- [shrink_to_fit](shrink_to_fit.md) - release unused index capacity
## Version history
- Added in version 3.13.0.
@@ -1,49 +0,0 @@
# <small>nlohmann::basic_json_document::</small>node_count
```cpp
std::size_t node_count() const noexcept;
```
Returns the number of entries in the document's flat index.
## Return value
The number of index entries: one per value (of any type, at any nesting depth) plus one per object key. `0` for a
[discarded](is_discarded.md) document.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
Each index entry is [16 bytes](../../home/architecture.md#node-index-of-json-views), so `#!cpp node_count() * 16` is
the size of the index itself (part, but not all, of [`memory_usage()`](memory_usage.md), which also counts decoded
strings and, for an owned document, the text).
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__node_count.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__node_count.output"
```
## See also
- [memory_usage](memory_usage.md) - the number of bytes held by the document
- [shrink_to_fit](shrink_to_fit.md) - release unused index capacity
## Version history
- Added in version 3.13.0.
@@ -1,49 +0,0 @@
# <small>nlohmann::basic_json_document::</small>owns_source
```cpp
bool owns_source() const noexcept;
```
Returns whether the document holds its own copy of the parsed text, as opposed to borrowing the caller's buffer.
## Return value
`#!cpp true` if the document owns the text returned by [`source()`](source.md), `#!cpp false` if it borrows it (or if
the document is [discarded](is_discarded.md)).
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
See the ownership table on [`parse`](parse.md#notes) for which inputs are borrowed and which are owned. A borrowed
document (`#!cpp owns_source() == false`) is only valid while the buffer it was parsed from is still alive.
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__owns_source.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__owns_source.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
- [parse_copy](parse_copy.md) - deserialize a copy of a compatible input, always owned
- [source](source.md) - the parsed text
## Version history
- Added in version 3.13.0.
@@ -1,154 +0,0 @@
# <small>nlohmann::basic_json_document::</small>parse
```cpp
// (1)
template<typename InputType>
static basic_json_document parse(InputType&& input,
const bool allow_exceptions = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
// (2)
template<typename IteratorType>
static basic_json_document parse(IteratorType first, IteratorType last,
const bool allow_exceptions = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
```
1. Deserialize from a compatible input, borrowing or owning it depending on its value category and type (see Notes).
2. Deserialize from a pair of input iterators.
Both overloads accept the same JSON text as [`BasicJsonType::parse()`](../basic_json/parse.md), with the same
`ignore_comments`/`ignore_trailing_commas` options, but build a [`basic_json_document`](index.md) (a flat index into
the input) instead of a tree of `BasicJsonType` values. The input must be byte-oriented (see the template parameters
below): not every input type of `BasicJsonType::parse()` is supported.
## Template parameters
`InputType`
: A byte-oriented input, one of:
- a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of single-byte characters
- a pointer to a null-terminated string of single-byte characters (`#!cpp char`, `#!cpp signed char`,
`#!cpp unsigned char`, `#!cpp std::uint8_t`)
- a container for which `#!cpp obj.data()` and `#!cpp obj.size()` give contiguous single-byte access, e.g.
`#!cpp std::vector<char>` or `#!cpp std::vector<std::uint8_t>`
- an `#!cpp std::istream` object
- a wide string object (`#!cpp std::wstring`, `#!cpp std::u16string`, `#!cpp std::u32string`), which is converted
to UTF-8
Other inputs are not supported: a `#!cpp FILE*`, and pointers to or arrays of wide characters (`#!cpp wchar_t`,
`#!cpp char16_t`, `#!cpp char32_t`) are rejected at compile time by a `#!cpp static_assert`. (Use
[`BasicJsonType::parse()`](../basic_json/parse.md) for these.)
`IteratorType`
: an input iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of
`#!cpp std::string::iterator`; the iterators of single-byte characters are borrowed or read like the byte inputs
above, those of wide characters are converted to UTF-8
## Parameters
`input` (in)
: Input to parse from.
`allow_exceptions` (in)
: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)
`ignore_comments` (in)
: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
(`#!cpp false`); (optional, `#!cpp false` by default)
`ignore_trailing_commas` (in)
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or
yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default)
`first` (in)
: iterator to the start of a character range
`last` (in)
: iterator to the end of a character range
## Return value
The parsed document. If `allow_exceptions` is `#!cpp false` and the input is not valid JSON, the returned document is
discarded; see [`is_discarded`](is_discarded.md).
## Exceptions
Throws the same exception [`BasicJsonType::parse()`](../basic_json/parse.md) throws for the same input and options --
the same exception id, message, and position -- because on a failing input the library's own parser is run on the
same bytes to produce the diagnostic. Additionally throws
[`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the input is 4294967280 bytes (4 GiB
minus 16 bytes) or larger, a size [`BasicJsonType::parse()`](../basic_json/parse.md) does not reject.
## Complexity
Linear in the length of the input.
## Notes
**Ownership.** Whether the document borrows `input` or owns a copy of it depends on its value category and type:
| `input` | ownership |
|--------------------------------------------------------------------------------------|--------------------------------------------------------------|
| lvalue byte container (`std::string`, `std::vector<char>`, ...), `std::string_view`, C string, character array | **borrowed** -- `input` must outlive the document |
| non-const rvalue `#!cpp std::string` | **owned**, moved in without a copy |
| other rvalue byte container (including a `#!cpp const` rvalue `#!cpp std::string`) | **owned**, copied |
| stream, wide string, or anything else read through the general input adapter | **owned**, read into a buffer (a stream is read to its end) |
For overload (2), a pair of pointers to single-byte integers (e.g. `#!cpp const char*`, `#!cpp std::uint8_t*`) is
borrowed. From C++20 on, so is any other contiguous iterator over single bytes, such as
`#!cpp std::vector<char>::iterator` or `#!cpp std::string::const_iterator`. Before C++20 these iterators cannot be
told apart from other class-type iterators, so their range is read into an owned buffer, as is any non-contiguous
range (e.g. of a `#!cpp std::list<char>`).
See [`owns_source`](owns_source.md) to check which happened after a call, and the
[feature page](../../features/json_view.md) for the reasoning.
**Numbers.** As for [`BasicJsonType::parse()`](../basic_json/parse.md), an integer literal too large for the 64-bit
integer type becomes a floating-point value.
**No lengths.** An integer argument that is not a `#!cpp bool` where the flags are expected -- for example
`#!cpp parse(ptr, len)` -- does not compile (the overload is deleted). Such a call would convert `len` to
`allow_exceptions` and read `ptr` as a null-terminated string, past the end of a buffer that has none. To parse a
buffer of a given length, pass a pair of pointers: `#!cpp parse(ptr, ptr + len)`. The same holds for
[`parse_copy`](parse_copy.md), [`accept`](accept.md), and [`read`](read.md).
## Examples
??? example "Example: (1) borrowed vs. owned input, and errors identical to `BasicJsonType::parse()`"
```cpp
--8<-- "examples/basic_json_document__parse.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__parse.output"
```
??? example "Example: (2) parse an iterator range (no NUL terminator required)"
```cpp
--8<-- "examples/basic_json_document__parse_iterator_pair.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__parse_iterator_pair.output"
```
## See also
- [parse_copy](parse_copy.md) - deserialize a copy of a compatible input
- [accept](accept.md) - check whether the input is valid JSON
- [read](read.md) - (re-)parse into this document, reusing its memory
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
- [`BasicJsonType::parse`](../basic_json/parse.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,80 +0,0 @@
# <small>nlohmann::basic_json_document::</small>parse_copy
```cpp
template<typename InputType>
static basic_json_document parse_copy(InputType&& input,
const bool allow_exceptions = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
```
Deserialize from a compatible input, always taking the document's own copy of it, regardless of the value category or
type of `input`. Unlike [`parse()`](parse.md), the returned document never depends on `input` staying alive.
## Template parameters
`InputType`
: A compatible input; see [`parse`](parse.md#template-parameters).
## Parameters
`input` (in)
: Input to parse from.
`allow_exceptions` (in)
: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)
`ignore_comments` (in)
: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
(`#!cpp false`); (optional, `#!cpp false` by default)
`ignore_trailing_commas` (in)
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or
yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default)
## Return value
The parsed document, with [`owns_source()`](owns_source.md) `#!cpp true`. If `allow_exceptions` is `#!cpp false` and
the input is not valid JSON, the returned document is discarded; see [`is_discarded`](is_discarded.md).
## Exceptions
Same as [`parse`](parse.md#exceptions).
## Complexity
Linear in the length of the input.
## Notes
`parse_copy()` accepts and rejects exactly what [`parse()`](parse.md) does, and classifies numbers the same way; it
only differs in that the input is always copied rather than sometimes borrowed. Prefer [`parse()`](parse.md) when the
input's lifetime already covers the document's, since it avoids the copy for borrowed inputs.
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp parse_copy(ptr, len)`, does not
compile; see [`parse`](parse.md#notes).
## Examples
??? example
The example below returns a document from a function whose local buffer would otherwise not outlive it.
```cpp
--8<-- "examples/basic_json_document__parse_copy.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__parse_copy.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input, borrowing it where possible
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
## Version history
- Added in version 3.13.0.
@@ -1,79 +0,0 @@
# <small>nlohmann::basic_json_document::</small>read
```cpp
template<typename InputType>
void read(InputType&& input,
const bool allow_exceptions = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
```
(Re-)parses `input` into `#!cpp *this`, discarding the document's previous value and reusing its memory (the node
index, the decoded-string buffer, and, if applicable, the owned copy of the text) rather than allocating a fresh
document. [`parse()`](parse.md) is implemented in terms of this function, applied to a default-constructed document.
## Template parameters
`InputType`
: A compatible input; see [`parse`](parse.md#template-parameters).
## Parameters
`input` (in)
: Input to parse from.
`allow_exceptions` (in)
: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)
`ignore_comments` (in)
: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
(`#!cpp false`); (optional, `#!cpp false` by default)
`ignore_trailing_commas` (in)
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or
yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default)
## Exceptions
Same as [`parse`](parse.md#exceptions).
## Complexity
Linear in the length of the input.
## Notes
Every view taken from `#!cpp *this` before the call -- including the previous [`root()`](root.md) -- is invalidated,
whether or not the new parse succeeds; take fresh views from [`root()`](root.md) afterward.
`input` is borrowed or owned by the same rules as [`parse()`](parse.md#notes); a document can borrow on one call and
own on the next, since ownership is decided freshly each time.
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp read(ptr, len)`, does not
compile; see [`parse`](parse.md#notes).
## Examples
??? example
The example below parses a sequence of messages into the same document, reusing its memory instead of allocating
a new document for each one.
```cpp
--8<-- "examples/basic_json_document__read.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__read.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
- [root](root.md) - the view of the root value
## Version history
- Added in version 3.13.0.
@@ -1,65 +0,0 @@
# <small>nlohmann::basic_json_document::</small>root
```cpp
// (1)
view_type root() const& noexcept;
// (2)
view_type root() const&& = delete;
```
1. Returns a view of the root value of the document.
2. Deleted: the view of a temporary document would dangle.
## Return value
A [`view_type`](index.md#member-types) (i.e. `#!cpp basic_json_view<BasicJsonType>`) for the root value, or a
discarded view if the document is [discarded](is_discarded.md).
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
**Lifetime.** A view refers into the document, so the document must outlive it. `root()` can therefore only be called
on a document that has a name (an lvalue); calling it on a temporary does not compile:
```cpp
auto v = json_document::parse(text).root(); // error: the document is destroyed at the end of the statement
auto doc = json_document::parse(text); // OK: keep the document alive
auto v = doc.root();
```
`root()` is a cheap handle into the document's index, not a copy of anything; call it as often as needed. The
returned view is valid under the same conditions as any other view of the document -- see
[Object inspection](../basic_json_view/index.md) -- in particular, it is invalidated by the next
[`read()`](read.md) or [`shrink_to_fit()`](shrink_to_fit.md) on this document.
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__root.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__root.output"
```
## See also
- [is_discarded](is_discarded.md) - return whether the last parse failed
- [materialize](../basic_json_view/materialize.md) - build the `BasicJsonType` value of a subtree
## Version history
- Added in version 3.13.0.
@@ -1,58 +0,0 @@
# <small>nlohmann::basic_json_document::</small>shrink_to_fit
```cpp
void shrink_to_fit();
```
Releases capacity that is no longer needed, both of the node index and of the buffer for decoded strings (strings that
contained escape sequences), e.g. after [`read()`](read.md) replaced a large document with a much smaller one. Like
`#!cpp std::vector::shrink_to_fit()`, this is a non-binding request: the library may keep more capacity than strictly
necessary.
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes to the document.
## Exceptions
May throw `#!cpp std::bad_alloc` if the reallocation fails; on exception, the document is unchanged.
## Complexity
Linear in [`node_count()`](node_count.md) plus the length of the decoded strings.
## Notes
!!! warning "Invalidates views"
Unlike moving the document, `shrink_to_fit()` **invalidates every view taken from this document before the
call**, including a previously obtained [`root()`](root.md): the node index is moved into a new, smaller
allocation, and the old one is freed. Take a fresh view from [`root()`](root.md) after calling this function.
This is unlike `#!cpp std::vector::shrink_to_fit()`, which promises nothing about validity but in practice often
leaves iterators alone when it did not need to reallocate; here, an implementation that avoids a reallocation when
possible would be an internal optimization only, not a guarantee to rely on.
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__shrink_to_fit.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__shrink_to_fit.output"
```
## See also
- [node_count](node_count.md) - the number of index entries
- [memory_usage](memory_usage.md) - the number of bytes held by the document
- [root](root.md) - the view of the root value
## Version history
- Added in version 3.13.0.
@@ -1,48 +0,0 @@
# <small>nlohmann::basic_json_document::</small>source
```cpp
view_type::string_view_t source() const noexcept;
```
Returns the parsed text, whether it is borrowed from the caller or owned by the document.
## Return value
A `#!cpp string_view_t` (`#!cpp std::string_view` on C++17 and newer) over the parsed text, or an empty one if the
document is [discarded](is_discarded.md).
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
For a borrowed document, `source()` points directly into the caller's buffer, so it is only valid while that buffer
is; see [`owns_source`](owns_source.md).
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__source.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__source.output"
```
## See also
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
- [source_offset](../basic_json_view/source_offset.md) - byte offset of a value in the source text
## Version history
- Added in version 3.13.0.
@@ -1,50 +0,0 @@
# <small>nlohmann::basic_json_view::</small>basic_json_view
```cpp
basic_json_view() noexcept = default;
```
Creates an invalid (discarded) view: [`type()`](type.md) is `#!cpp value_t::discarded` and
[`is_discarded()`](is_discarded.md) is `#!cpp true`.
This is the only constructor a caller can use directly. Every other view is obtained from a
[`basic_json_document`](../basic_json_document/index.md), via [`root()`](../basic_json_document/root.md) or (once
element access is added) from navigating into a container.
## Exception safety
No-throw guarantee: this constructor never throws exceptions.
## Complexity
Constant.
## Notes
`basic_json_view` is trivially copyable (it holds two pointers), so a default-constructed view can be used as a
placeholder for "no value yet" and later be assigned a real view.
## Examples
??? example
The example below shows the default constructor and that a `basic_json_view` is a small, copyable handle.
```cpp
--8<-- "examples/basic_json_view__basic_json_view.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__basic_json_view.output"
```
## See also
- [is_discarded](is_discarded.md) - return whether the view is invalid
- [root](../basic_json_document/root.md) - the view of a document's root value
## Version history
- Added in version 3.13.0.
@@ -1,61 +0,0 @@
# <small>nlohmann::basic_json_view::</small>empty
```cpp
bool empty() const noexcept;
```
Checks whether [`size()`](size.md) is `0`, as [`BasicJsonType::empty()`](../basic_json/empty.md) would for the same
value.
## Return value
The return value depends on the type and is defined as follows:
| Value type | return value |
|----------------------|-----------------|
| null | `#!cpp true` |
| discarded | `#!cpp true` |
| boolean | `#!cpp false` |
| string | `#!cpp false` |
| number | `#!cpp false` |
| object | `#!cpp object_t::empty()` |
| array | `#!cpp array_t::empty()` |
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
As for [`BasicJsonType::empty()`](../basic_json/empty.md), this does not return whether a string value is empty -- it
is `#!cpp false` for any string, regardless of its length.
## Examples
??? example
The example below uses [`size()`](size.md) and `empty()` to decide whether a parsed message is worth acting on,
without materializing it into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__size_empty.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__size_empty.output"
```
## See also
- [size](size.md) - return the number of elements
- [`BasicJsonType::empty`](../basic_json/empty.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,81 +0,0 @@
# <small>nlohmann::</small>basic_json_view
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
template<typename BasicJsonType>
class basic_json_view;
```
A read-only handle to one value of a [`basic_json_document`](../basic_json_document/index.md): two pointers (a pointer
to the document and a pointer into its index), trivially copyable. A view is valid as long as
- the document is alive,
- the document has not been re-parsed with [`read()`](../basic_json_document/read.md) (or
[`parse()`](../basic_json_document/parse.md) into it) or shrunk with
[`shrink_to_fit()`](../basic_json_document/shrink_to_fit.md) since the view was taken, and
- if the document borrows its source text, that text is still alive.
Moving the document itself does not invalidate its views: the index is heap-allocated independently of the
`basic_json_document` object.
`basic_json_view` provides the read-only part of the `BasicJsonType` interface: the type-inspection functions, and
[`materialize()`](materialize.md) to build the `BasicJsonType` value of a subtree on demand. It does not (yet) provide
element access, iteration, `get<T>()`, JSON Pointer support, `dump()`, or comparison.
## Template parameters
`BasicJsonType`
: a specialization of [`basic_json`](../basic_json/index.md), matching the
[`basic_json_document`](../basic_json_document/index.md) the view was taken from.
## Specializations
- [**json_view**](../json_view.md) - views of a [`json_document`](../json_document.md)
- [**ordered_json_view**](../ordered_json_view.md) - views of an [`ordered_json_document`](../ordered_json_document.md)
## Member types
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
- **string_t**, **number_integer_t**, **number_unsigned_t**, **number_float_t**, **json_pointer** - the corresponding
member types of `BasicJsonType`
- **size_type** - `#!cpp std::size_t`
- **string_view_t** - `#!cpp std::string_view` on C++17 and newer, a minimal internal substitute otherwise
## Member functions
- [(constructor)](basic_json_view.md)
### Object inspection
- [**type**](type.md) - return the type of the value
- [**is_null**](is_null.md) - return whether the value is null
- [**is_boolean**](is_boolean.md) - return whether the value is a boolean
- [**is_number**](is_number.md) - return whether the value is a number
- [**is_number_integer**](is_number_integer.md) - return whether the value is an integer number
- [**is_number_unsigned**](is_number_unsigned.md) - return whether the value is an unsigned integer number
- [**is_number_float**](is_number_float.md) - return whether the value is a floating-point number
- [**is_string**](is_string.md) - return whether the value is a string
- [**is_array**](is_array.md) - return whether the value is an array
- [**is_object**](is_object.md) - return whether the value is an object
- [**is_binary**](is_binary.md) - return whether the value is a binary array (always `#!cpp false`)
- [**is_primitive**](is_primitive.md) - return whether the type is primitive
- [**is_structured**](is_structured.md) - return whether the type is structured
- [**is_discarded**](is_discarded.md) - return whether the view is invalid
### Capacity
- [**size**](size.md) - return the number of elements
- [**empty**](empty.md) - return whether the value has no elements
### Conversion
- [**materialize**](materialize.md) - build the `BasicJsonType` value of this subtree
### Source access
- [**source_offset**](source_offset.md) - byte offset of this value in the document's source text
## Version history
- Added in version 3.13.0.
@@ -1,46 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_array
```cpp
bool is_array() const noexcept;
```
This function returns `#!cpp true` if and only if the value is an array.
## Return value
`#!cpp true` if the type is an array, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_structured](is_structured.md) - return whether the type is structured
- [size](size.md), [empty](empty.md) - the number of elements, and whether there are none
- [`BasicJsonType::is_array`](../basic_json/is_array.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,46 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_binary
```cpp
bool is_binary() const noexcept;
```
This function always returns `#!cpp false`: a JSON text has no binary values, so a view can never refer to one. The
function exists for interface parity with [`BasicJsonType::is_binary`](../basic_json/is_binary.md).
## Return value
`#!cpp false`, always.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [type](type.md) - return the type of the value
- [`BasicJsonType::is_binary`](../basic_json/is_binary.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,45 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_boolean
```cpp
bool is_boolean() const noexcept;
```
This function returns `#!cpp true` if and only if the value is a boolean.
## Return value
`#!cpp true` if the type is a boolean, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [type](type.md) - return the type of the value
- [`BasicJsonType::is_boolean`](../basic_json/is_boolean.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,55 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_discarded
```cpp
bool is_discarded() const noexcept;
```
Returns whether this view is invalid, i.e. does not refer to a value. This is the case for a default-constructed
view (see [(constructor)](basic_json_view.md)), and for [`root()`](../basic_json_document/root.md) of a document
that is itself [discarded](../basic_json_document/is_discarded.md) -- in particular, the root of a failed
[`parse()`](../basic_json_document/parse.md) with `allow_exceptions` set to `#!cpp false`.
## Return value
`#!cpp true` if the view is discarded, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
A `basic_json_view` is not convertible to `#!cpp bool`: such a conversion would mean "refers to a value", whereas
`basic_json` converts to the `#!cpp bool` it holds, so the same code would silently behave differently. Test
`#!cpp !v.is_discarded()` explicitly.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [(constructor)](basic_json_view.md) - the default constructor creates a discarded view
- [is_discarded (basic_json_document)](../basic_json_document/is_discarded.md) - return whether the last parse failed
- [`BasicJsonType::is_discarded`](../basic_json/is_discarded.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,45 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_null
```cpp
bool is_null() const noexcept;
```
This function returns `#!cpp true` if and only if the value is `#!json null`.
## Return value
`#!cpp true` if the type is `#!json null`, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [type](type.md) - return the type of the value
- [`BasicJsonType::is_null`](../basic_json/is_null.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,47 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_number
```cpp
bool is_number() const noexcept;
```
This function returns `#!cpp true` if and only if the value is a number, i.e. an integer, unsigned integer, or floating-point value. It is defined as `#!cpp is_number_integer() || is_number_float()`.
## Return value
`#!cpp true` if the type is a number, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_number_integer](is_number_integer.md) - return whether the value is an integer or unsigned integer number
- [is_number_unsigned](is_number_unsigned.md) - return whether the value is an unsigned integer number
- [is_number_float](is_number_float.md) - return whether the value is a floating-point number
- [`BasicJsonType::is_number`](../basic_json/is_number.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,51 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_number_float
```cpp
bool is_number_float() const noexcept;
```
This function returns `#!cpp true` if and only if the value is a floating-point number.
## Return value
`#!cpp true` if the type is `#!cpp value_t::number_float`, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
As for [`BasicJsonType::parse`](../basic_json/parse.md), an integer literal that does not fit into the 64-bit
integer type is classified as a floating-point number, so `is_number_float()` can be `#!cpp true` even for an
integer-looking token in the source text.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_number](is_number.md) - return whether the value is a number
- [`BasicJsonType::is_number_float`](../basic_json/is_number_float.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,51 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_number_integer
```cpp
bool is_number_integer() const noexcept;
```
This function returns `#!cpp true` if and only if the value is an integer or unsigned integer number.
## Return value
`#!cpp true` if the type is `#!cpp value_t::number_integer` or `#!cpp value_t::number_unsigned`, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
As for [`BasicJsonType::is_number_integer`](../basic_json/is_number_integer.md), this includes unsigned integer
values; use [`is_number_unsigned`](is_number_unsigned.md) to test for those specifically.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_number](is_number.md) - return whether the value is a number
- [is_number_unsigned](is_number_unsigned.md) - return whether the value is an unsigned integer number
- [`BasicJsonType::is_number_integer`](../basic_json/is_number_integer.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,45 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_number_unsigned
```cpp
bool is_number_unsigned() const noexcept;
```
This function returns `#!cpp true` if and only if the value is an unsigned integer number.
## Return value
`#!cpp true` if the type is `#!cpp value_t::number_unsigned`, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_number_integer](is_number_integer.md) - return whether the value is an integer or unsigned integer number
- [`BasicJsonType::is_number_unsigned`](../basic_json/is_number_unsigned.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,46 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_object
```cpp
bool is_object() const noexcept;
```
This function returns `#!cpp true` if and only if the value is an object.
## Return value
`#!cpp true` if the type is an object, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_structured](is_structured.md) - return whether the type is structured
- [size](size.md), [empty](empty.md) - the number of elements, and whether there are none
- [`BasicJsonType::is_object`](../basic_json/is_object.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,46 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_primitive
```cpp
bool is_primitive() const noexcept;
```
This function returns `#!cpp true` if and only if the value is primitive, i.e. `#!json null`, a boolean, a number, or a string. It is defined as `#!cpp is_null() || is_string() || is_boolean() || is_number()`.
## Return value
`#!cpp true` if the type is primitive, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_structured](is_structured.md) - return whether the type is structured (the complement of this function, for a
non-discarded view)
- [`BasicJsonType::is_primitive`](../basic_json/is_primitive.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,45 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_string
```cpp
bool is_string() const noexcept;
```
This function returns `#!cpp true` if and only if the value is a string.
## Return value
`#!cpp true` if the type is a string, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [source_offset](source_offset.md) - byte offset of this value in the document's source text
- [`BasicJsonType::is_string`](../basic_json/is_string.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,46 +0,0 @@
# <small>nlohmann::basic_json_view::</small>is_structured
```cpp
bool is_structured() const noexcept;
```
This function returns `#!cpp true` if and only if the value is structured, i.e. an array or an object. It is defined as `#!cpp is_array() || is_object()`.
## Return value
`#!cpp true` if the type is structured, `#!cpp false` otherwise.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_primitive](is_primitive.md) - return whether the type is primitive
- [size](size.md), [empty](empty.md) - the number of elements, and whether there are none
- [`BasicJsonType::is_structured`](../basic_json/is_structured.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,69 +0,0 @@
# <small>nlohmann::basic_json_view::</small>materialize
```cpp
BasicJsonType materialize() const;
```
Builds the `BasicJsonType` value of this subtree: the value [`BasicJsonType::parse()`](../basic_json/parse.md) would
have produced for the same source text, allocated for the first time by this call.
## Return value
The `BasicJsonType` value of this subtree, or a discarded `BasicJsonType` value (`#!cpp BasicJsonType(value_t::discarded)`)
if the view is [discarded](is_discarded.md).
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes to the view or the document it refers to (nothing
about either is mutated by this function).
## Exceptions
May throw `#!cpp std::bad_alloc` (via `BasicJsonType`'s allocator) if constructing the result fails.
## Complexity
Linear in the size of the subtree.
## Notes
`materialize()` replays the subtree through the same SAX builder [`BasicJsonType::parse()`](../basic_json/parse.md)
uses internally, so the result matches it exactly -- including, for an object, that a repeated key keeps only its
last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion
would be; the JSON nesting depth is limited only by available memory, as for `BasicJsonType::parse()` itself.
Unlike parsing with [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) enabled, the values
produced by `materialize()` do not carry source positions: there is no lexer run during the replay to record them.
Calling `materialize()` on the same view repeatedly builds a new, independent `BasicJsonType` value each time; it
never caches the result.
## Examples
??? example
The example below skips messages that are not useful -- a discarded value, or an empty array -- using only
[`is_array()`](is_array.md) and [`empty()`](empty.md), and calls `materialize()` only for the messages that are
actually used, so no `BasicJsonType` value (and none of its per-element allocations) is ever built for the
skipped ones.
```cpp
--8<-- "examples/basic_json_view__materialize.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__materialize.output"
```
## See also
- [root](../basic_json_document/root.md) - the view of a document's root value
- [`BasicJsonType::parse`](../basic_json/parse.md) - build a `BasicJsonType` value directly from a JSON text
- [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) - source positions on parsed values (not
produced by `materialize()`)
## Version history
- Added in version 3.13.0.
@@ -1,60 +0,0 @@
# <small>nlohmann::basic_json_view::</small>size
```cpp
size_type size() const noexcept;
```
Returns the number of elements, as [`BasicJsonType::size()`](../basic_json/size.md) would for the same value.
## Return value
The return value depends on the type and is defined as follows:
| Value type | return value |
|----------------------|-----------------------------|
| null | `0` |
| discarded | `0` |
| boolean | `1` |
| string | `1` |
| number | `1` |
| object | number of key/value pairs |
| array | number of elements |
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant: for an object or array, the element count is stored in the index, not counted on demand.
## Notes
As for [`BasicJsonType::size()`](../basic_json/size.md), this does not return the length of a string value -- it is
`1` for a string, regardless of its length.
## Examples
??? example
The example below uses `size()` and [`empty()`](empty.md) to decide whether a parsed message is worth acting on,
without materializing it into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__size_empty.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__size_empty.output"
```
## See also
- [empty](empty.md) - return whether the value has no elements
- [`BasicJsonType::size`](../basic_json/size.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -1,55 +0,0 @@
# <small>nlohmann::basic_json_view::</small>source_offset
```cpp
std::size_t source_offset() const noexcept;
```
Returns the byte offset of this value in the document's [`source()`](../basic_json_document/source.md) text, without
materializing anything.
## Return value
- For a string with no escapes, a number, `#!json true`/`#!json false`/`#!json null`, an array, or an object: the
byte offset of the first byte of the value's token (for a string: the first byte after the opening quote) in
[`source()`](../basic_json_document/source.md).
- `#!cpp static_cast<std::size_t>(-1)` for a [discarded](is_discarded.md) view, and for a string that contains
escapes -- such a string was decoded once into the document's own buffer, so there is no single byte range in
`source()` left to point at.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
This is a raw offset, not a length: the API does not (yet) expose how many bytes the token occupies in the source
text, so `source_offset()` alone is enough to report *where* a value came from (for an error message, for syntax
highlighting, ...) but not to slice its exact text back out of [`source()`](../basic_json_document/source.md) for a
string, whose token length is not the same as its decoded [`size()`](size.md).
## Examples
??? example
```cpp
--8<-- "examples/basic_json_view__source_offset.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__source_offset.output"
```
## See also
- [source](../basic_json_document/source.md) - the parsed text
- [is_string](is_string.md) - return whether the value is a string
## Version history
- Added in version 3.13.0.
@@ -1,53 +0,0 @@
# <small>nlohmann::basic_json_view::</small>type
```cpp
value_t type() const noexcept;
```
Returns the type of the value this view refers to, as a value from the [`value_t`](../basic_json/value_t.md)
enumeration -- the same enumeration [`BasicJsonType::type()`](../basic_json/type.md) uses.
## Return value
The type of the value; `#!cpp value_t::discarded` for a [discarded](is_discarded.md) view.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
Unlike [`BasicJsonType::type()`](../basic_json/type.md), this function can never return `#!cpp value_t::binary`: a
JSON text has no binary values, so `type()` only distinguishes the eight ordinary JSON value types (plus
`#!cpp discarded`).
## Examples
??? example
The example below classifies several parsed documents by the type of their root value, without materializing any
of them into a `BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__type_predicates.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__type_predicates.output"
```
## See also
- [is_null](is_null.md), [is_boolean](is_boolean.md), [is_number](is_number.md), [is_string](is_string.md),
[is_array](is_array.md), [is_object](is_object.md) - type-specific predicates built on `type()`
- [`BasicJsonType::type`](../basic_json/type.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
-35
View File
@@ -1,35 +0,0 @@
# <small>nlohmann::</small>json_document
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using json_document = basic_json_document<json>;
```
This type is a [`basic_json_document`](basic_json_document/index.md) of the default [`json`](json.md)
specialization.
## Examples
??? example
The example below demonstrates how to use the type `nlohmann::json_document`.
```cpp
--8<-- "examples/json_document.cpp"
```
Output:
```json
--8<-- "examples/json_document.output"
```
## See also
- [json_view](json_view.md) - a view of a value of a `json_document`
- [ordered_json_document](ordered_json_document.md) - the corresponding document for `ordered_json`
## Version history
Since version 3.13.0.
-34
View File
@@ -1,34 +0,0 @@
# <small>nlohmann::</small>json_view
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using json_view = basic_json_view<json>;
```
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of a [`json_document`](json_document.md).
## Examples
??? example
The example below demonstrates how to use the type `nlohmann::json_view`.
```cpp
--8<-- "examples/json_view.cpp"
```
Output:
```json
--8<-- "examples/json_view.output"
```
## See also
- [json_document](json_document.md) - the document type this view refers into
- [ordered_json_view](ordered_json_view.md) - the corresponding view for `ordered_json_document`
## Version history
Since version 3.13.0.
@@ -1,38 +0,0 @@
# <small>nlohmann::</small>ordered_json_document
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using ordered_json_document = basic_json_document<ordered_json>;
```
This type is a [`basic_json_document`](basic_json_document/index.md) of the [`ordered_json`](ordered_json.md)
specialization: [`materialize()`](basic_json_view/materialize.md) on one of its views preserves the insertion order
of object keys, instead of sorting them like [`json_document`](json_document.md) does.
## Examples
??? example
The example below demonstrates how `ordered_json_document` preserves the insertion order of object keys when
materializing.
```cpp
--8<-- "examples/ordered_json_document.cpp"
```
Output:
```json
--8<-- "examples/ordered_json_document.output"
```
## See also
- [ordered_json_view](ordered_json_view.md) - a view of a value of an `ordered_json_document`
- [json_document](json_document.md) - the corresponding document for the default `json` specialization
- [Object Order](../features/object_order.md)
## Version history
Since version 3.13.0.
-35
View File
@@ -1,35 +0,0 @@
# <small>nlohmann::</small>ordered_json_view
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using ordered_json_view = basic_json_view<ordered_json>;
```
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of an
[`ordered_json_document`](ordered_json_document.md).
## Examples
??? example
The example below demonstrates how to use the type `nlohmann::ordered_json_view`.
```cpp
--8<-- "examples/ordered_json_view.cpp"
```
Output:
```json
--8<-- "examples/ordered_json_view.output"
```
## See also
- [ordered_json_document](ordered_json_document.md) - the document type this view refers into
- [json_view](json_view.md) - the corresponding view for `json_document`
## Version history
Since version 3.13.0.
@@ -1,19 +0,0 @@
#include <iostream>
#include <nlohmann/json.hpp>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
std::cout << std::boolalpha;
// accept() behaves exactly like basic_json::accept(): the same inputs are
// accepted or rejected, with the same ignore_comments/ignore_trailing_commas
// options
std::cout << json_document::accept(R"({"a": 1})") << '\n';
std::cout << json_document::accept(R"({"a": 1,})") << '\n'; // trailing comma: rejected by default
std::cout << json_document::accept(R"({"a": 1,})", false, true) << '\n'; // ignore_trailing_commas
std::cout << (json_document::accept(R"({"a": 1})") == nlohmann::json::accept(R"({"a": 1})")) << '\n';
}
@@ -1,4 +0,0 @@
true
false
true
true
@@ -1,23 +0,0 @@
#include <iostream>
#include <utility>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
std::cout << std::boolalpha;
// the default constructor creates an empty (discarded) document
json_document empty;
std::cout << empty.is_discarded() << '\n';
// json_document is move-only: parse() itself returns by value (moved out),
// and a document can be moved again, e.g. into a container
json_document doc = json_document::parse(R"({"a": 1})");
json_document moved = std::move(doc);
std::cout << moved.root().is_object() << '\n';
// copying is disabled at compile time:
// json_document another = moved; // does not compile
}
@@ -1,2 +0,0 @@
true
true
@@ -1,19 +0,0 @@
#include <iostream>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
std::cout << std::boolalpha;
// with allow_exceptions == false, a parse error produces a discarded
// document instead of throwing -- exactly like basic_json::parse()
json_document doc = json_document::parse(R"({"a": )", /* allow_exceptions */ false);
std::cout << doc.is_discarded() << '\n';
std::cout << doc.root().is_discarded() << '\n';
// a successful parse is never discarded
json_document ok = json_document::parse(R"({"a": 1})", false);
std::cout << ok.is_discarded() << '\n';
}
@@ -1,3 +0,0 @@
true
true
false
@@ -1,28 +0,0 @@
#include <iostream>
#include <string>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
std::cout << std::boolalpha;
// long enough that copying it needs a real (heap) allocation, so the
// comparison below does not depend on the standard library's small
// string optimization threshold
const std::string text = std::string(200, ' ') + "[1, 2, 3, 4, 5]";
// memory_usage() is not portable across platforms/allocators/compilers, so
// compare it relatively instead of printing the raw byte count
json_document borrowed = json_document::parse(text);
json_document owned = json_document::parse_copy(text);
// the owned document additionally stores its own copy of the source text
std::cout << (owned.memory_usage() > borrowed.memory_usage()) << '\n';
// a document with more values needs a larger index
json_document small = json_document::parse(std::string("[1]"));
json_document large = json_document::parse(std::string("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"));
std::cout << (large.memory_usage() > small.memory_usage()) << '\n';
}
@@ -1,2 +0,0 @@
true
true
@@ -1,15 +0,0 @@
#include <iostream>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
// node_count() is the size of the flat index: one 16-byte node per value,
// plus one per object key (values and keys are all the index stores)
json_document scalar = json_document::parse("42");
std::cout << scalar.node_count() << '\n';
json_document doc = json_document::parse(R"({"a": 1, "b": [1, 2]})");
std::cout << doc.node_count() << '\n';
}
@@ -1,2 +0,0 @@
1
7
@@ -1,24 +0,0 @@
#include <iostream>
#include <string>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
std::cout << std::boolalpha;
std::string text = R"({"a": 1})";
// borrowed: the document only points into `text`; `text` must outlive it
json_document borrowed = json_document::parse(text);
std::cout << borrowed.owns_source() << '\n';
// owned: parse_copy() always takes its own copy
json_document copied = json_document::parse_copy(text);
std::cout << copied.owns_source() << '\n';
// owned: an rvalue std::string is moved in, not copied, but still owned
json_document moved_in = json_document::parse(std::string(text));
std::cout << moved_in.owns_source() << '\n';
}
@@ -1,3 +0,0 @@
false
true
true
@@ -1,33 +0,0 @@
#include <iostream>
#include <string>
#include <nlohmann/json.hpp>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
std::cout << std::boolalpha;
// an lvalue std::string is BORROWED: the document only stores a pointer
// into `text`, so `text` must outlive `borrowed`
std::string text = R"({"count": 3})";
json_document borrowed = json_document::parse(text);
std::cout << borrowed.owns_source() << '\n'; // false
// an rvalue std::string is MOVED into the document -- no copy of the text
json_document owned = json_document::parse(std::string(R"({"count": 3})"));
std::cout << owned.owns_source() << '\n'; // true
// errors are identical to basic_json::parse: same exception id, message,
// and position, because the library parser runs on the same bytes on a
// failing input
try
{
static_cast<void>(json_document::parse(R"({"count": )"));
}
catch (const nlohmann::json::parse_error& e)
{
std::cout << e.id << '\n';
}
}
@@ -1,3 +0,0 @@
false
true
101
@@ -1,22 +0,0 @@
#include <iostream>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
json_document parse_from_temporary_buffer()
{
char buffer[] = R"({"a": 1})";
// parse() would borrow `buffer`, which is about to go out of scope;
// parse_copy() takes its own copy instead, so the returned document does
// not depend on `buffer` afterward
return json_document::parse_copy(buffer);
}
int main()
{
std::cout << std::boolalpha;
json_document doc = parse_from_temporary_buffer();
std::cout << doc.owns_source() << '\n';
std::cout << doc.root().is_object() << '\n';
}
@@ -1,2 +0,0 @@
true
true
Loaded 100 of 209 files, more files were not shown because too many files have changed in this diff. Show more