Compare commits

...
Author SHA1 Message Date
Niels Lohmann 75ef044426 Merge branch 'json-view/16-view-simd' into json-view/19-edit-set
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:39:45 +02:00
Niels Lohmann 1ec2d710f7 Merge branch 'json-view/13-view-dump' into json-view/16-view-simd
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:39:42 +02:00
Niels Lohmann 8860bf6f3a Merge branch 'json-view/11-view-access' into json-view/13-view-dump
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:39:40 +02:00
Niels Lohmann 7852da2bc2 Merge branch 'json-view/08-view-builder' into json-view/11-view-access
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:39:37 +02:00
Niels Lohmann 0012f65f60 Merge branch 'json-view/23-zmij' into json-view/08-view-builder
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:39:35 +02:00
Niels Lohmann 4c43e03d40 Merge CI fixes into json-view/23-zmij
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:39:25 +02:00
Niels Lohmann 9962b3cf43 Merge branch 'json-view/16-view-simd' into json-view/19-edit-set
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

# Conflicts:
#	include/nlohmann/detail/view/document_data.hpp
#	single_include/nlohmann/json_view.hpp
2026-10-08 16:33:54 +02:00
Niels Lohmann d22193a8b6 Fix CI findings in the Zmij writer and its tests
- bit_ops.hpp: include macro_scope.hpp (JSON_HEDLEY_ALWAYS_INLINE); fixes IWYU
- to_chars.hpp: C4100 for the unused parameter in release builds, clang-tidy
  sign comparison, cpplint runtime/int, GCC -Wstrict-overflow (unsigned abs)
- unit-to_chars.cpp: parse with the library instead of strtod (MinGW's strtod
  rounds some 16/17 digit inputs wrongly); no floating-point std::to_chars
  with icpc

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:33:32 +02:00
Niels Lohmann 4f1c34e44d Merge branch 'json-view/13-view-dump' into json-view/16-view-simd
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

# Conflicts:
#	include/nlohmann/detail/view/document_data.hpp
#	single_include/nlohmann/json_view.hpp
2026-10-08 16:29:14 +02:00
Niels Lohmann 5db2fa633c Merge branch 'json-view/11-view-access' into json-view/13-view-dump
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:27:26 +02:00
Niels Lohmann acde46421b Merge branch 'json-view/08-view-builder' into json-view/11-view-access
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:27:24 +02:00
Niels Lohmann 30417e9e74 Exclude libstdc++'s string_view comparison from the sign-change check
basic_string_view::_S_compare stores the difference of two lengths in a
signed difference_type on purpose, which -fsanitize=integer reports for
every comparison with a shorter view (test-json_view_cpp17).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:27:15 +02:00
Niels Lohmann 63396cbe00 Merge branch 'json-view/23-zmij' into json-view/08-view-builder
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

# Conflicts:
#	Makefile
#	meson.build
2026-10-08 16:26:33 +02:00
Niels Lohmann d9a0844723 Fix document_data for old Clang (3.4-3.6)
Drop the empty braced NSDMIs of the std::string members: old Clang
rejects the defaulted constructor when it is used by a member
initializer before the end of the class definition.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:25:45 +02:00
Niels Lohmann 22b82b487b Merge branch 'json-view/02b-float-parser' into json-view/23-zmij
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:25:42 +02:00
Niels Lohmann 9c7eb12918 Fix GCC module build and MSVC C4127 in the json_view SIMD code
GCC ignores the target attribute in modules, so the SSSE3 dispatch is
disabled for the module interface (the check stays portable, SSE2 is kept).
Make the 8-vs-16 byte unrolling condition in scan_string_run a
preprocessor/template split to avoid a constant condition (C4127).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:23:21 +02:00
Niels Lohmann 2105149798 Fix old clang and MSVC C4127 in editable json documents
Value-initialize the const std::less in find_parent (clang 3.4/3.6 do not
implement DR 253), and test the Editable template argument through a
function to avoid MSVC C4127.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:22:47 +02:00
Niels Lohmann a7de414ce8 Avoid raw string with escapes inside CHECK macro (MSVC C2017)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:19:11 +02:00
Niels Lohmann 43c75bef51 Merge branch 'develop' into json-view/02b-float-parser
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

# Conflicts:
#	tests/src/unit-class_lexer.cpp
2026-10-08 16:19:06 +02:00
Niels Lohmann 3d7f554927 Use the with_*_t aliases in tests, examples, and docs (#5787)
* Use the with_*_t aliases in tests, examples, and docs

Replace spelled-out basic_json<...> instantiations that only change one
or two template parameters with nlohmann::json::with_*_t (or
ordered_json::with_*_t when the object type is ordered_map). Types that
change all three number types chain with_integers_t and with_float_t.

The raw basic_json<...> spelling stays where the template parameter
list itself is the subject: the alias tests in unit-udt.cpp, explicit
instantiations, and the ordered_json/compile-time docs.

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

* Fix unit-large_json for clang and JSON_DIAGNOSTICS

Two test problems from #5781 broke CI on develop: CAPTURE(depth); trips
clang's -Wextra-semi-stmt, and the type_error.321 messages did not
account for the diagnostics path prefix.

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

* Use static_cast in unit-hash for clang-tidy

#5772 added functional casts that clang-tidy reports as C-style casts
(google-readability-casting). Also append a char instead of a
one-character string in unit-large_json.

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

* Declare the expected message prefix const in unit-large_json

Without JSON_DIAGNOSTICS the prefix was never modified, which
clang-tidy reports (misc-const-correctness).

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-08 16:11:16 +02:00
Suyog Verma a269794db7 Use MSVC intrinsics for full multiplication (#5782)
* Use MSVC intrinsics for full multiplication

Signed-off-by: Suyog Verma <suyogverma0057@gmail.com>

* Fix formatting in unit-class_lexer

Signed-off-by: Suyog Verma <suyogverma0057@gmail.com>

* Address review feedback

Signed-off-by: Suyog Verma <suyogverma0057@gmail.com>

---------

Signed-off-by: Suyog Verma <suyogverma0057@gmail.com>
2026-10-08 08:49:32 +02:00
Niels LohmannandDylan Baker ed8ba0201f Install CMake package config files with Meson, and add Meson options (#5587)
* Install CMake package config files with Meson, and add Meson options

Squashed onto develop from:
- Install CMake package config files with Meson
- meson: Indent code inside an if block
- meson: set a minimum Meson version
- meson: use `override_dependency()` to set dependencies
- meson: use `install_subdir` for headers
- meson: set the C++ standard to C++11
- meson: handle single header and multiheader the same way CMake does
- meson: add support for the GlobalUDLs option
- meson: add support for the ImplictConversions option
- Add meson information to FILES.md
- Complete the Meson options and match CMake's compile definitions
- Add the JSON_* definitions to the CMake pkg-config file
- Document the Meson options and check them in CI
- Fix the Meson CMake target for includedir or datadir outside the prefix
- Avoid //include in Meson-generated CMake target for prefix /
- Add DisableTupleReferenceConversion to Meson and the CMake pkg-config file
- Check in CI that Meson and pkg-config offer the CMake options
- Remove accidentally committed Python bytecode

Co-authored-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Add the StrictBinaryUTF8 and DeleteDeprecatedFunctions Meson options

JSON_StrictBinaryUTF8 (#5741) and JSON_DeleteDeprecatedFunctions (#5755)
arrived with develop but were missing from the Meson build and the
pkg-config file, so check_build_options failed. Both Meson options
default to false and add JSON_STRICT_BINARY_UTF8=1 and
JSON_DELETE_DEPRECATED_FUNCTIONS=1 to the dependency, the pkg-config
file, and the generated CMake target; CMake's pkg-config file now
carries both definitions too. The ci_meson_install job sets and checks
them in its non-default install.

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

---------

Signed-off-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Dylan Baker <dylan@pnwbakers.com>
2026-10-07 22:20:05 +02:00
Niels Lohmann 0a4c6d1a8f Merge branch 'json-view/16-view-simd' into json-view/19-edit-set
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:52 +02:00
Niels Lohmann ad715372bf Merge branch 'json-view/13-view-dump' into json-view/16-view-simd
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:50 +02:00
Niels Lohmann c39680779c Merge branch 'json-view/11-view-access' into json-view/13-view-dump
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:47 +02:00
Niels Lohmann dfdd69d234 Merge branch 'json-view/08-view-builder' into json-view/11-view-access
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:44 +02:00
Niels Lohmann 33b7b30d06 Merge branch 'json-view/23-zmij' into json-view/08-view-builder
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:42 +02:00
Niels Lohmann cb3c0177ed Merge branch 'json-view/02b-float-parser' into json-view/23-zmij
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:39 +02:00
Niels Lohmann 39d34f30ba Merge branch 'develop' into json-view/02b-float-parser
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:13 +02:00
Niels Lohmann 88ddacb84b Fix CI warnings in own float parser
- pow5_table.hpp: pow5_128_largest_power was unused in this branch's
  own code (GCC -Werror=unused-const-variable); tie it to the table
  size with a static_assert instead of removing it, since a later
  branch in the stack (json-view/23-zmij) uses it.
- number_parse.hpp: rename the local variable `copy` to `buffer` to
  satisfy cpplint's build/include_what_you_use check.
- unit-class_lexer.cpp: extend the NOLINT list on the seeded mt19937
  with bugprone-random-generator-seed, and parenthesize
  `8 * sizeof(Bits) - 1` for clang-tidy.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 20:26:12 +02:00
Niels LohmannandAfonso Januário a5f5d3059b Make std::hash<basic_json> consistent with operator== for numbers (#5772)
* Make std::hash<basic_json> consistent with operator== for numbers

operator== converts between number_integer, number_unsigned, and
number_float before comparing, so json(0), json(0U), and json(0.0)
all compare equal. hash() folded the specific value_t into the
result for each of the three numeric cases, giving each a distinct
hash and breaking the standard Hash requirement that a == b implies
hash(a) == hash(b). A std::unordered_set could therefore hold all
three as separate elements even though they compare equal.

hash() now treats all three numeric variants the same way: it
converts the value to number_float_t and combines it with a single
shared type tag, so any two numbers operator== considers equal hash
identically regardless of which internal type actually holds them.

Updated the accompanying test to check this consistency directly
(including via an actual unordered_set) instead of asserting that 0,
0U, and 0.0 hash differently, since that assumption was the bug.
Also corrected the function's own doc comment and the std::hash API
docs, which described the old behavior as intended.

Fixes #5400

Signed-off-by: Afonso Januário <afonso-januario@hotmail.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Remove now-unused number_integer_t/number_unsigned_t typedefs in hash()

Merging the three numeric branches into one that only reads
number_float_t left these two aliases unused, which several CI
configurations treat as a build error under -Wunused-local-typedefs.

Signed-off-by: Afonso Januário <afonso-januario@hotmail.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Mark the unordered_set in the hash regression test const

clang-tidy's misc-const-correctness check flagged it: the set is
never mutated after construction, only read via size().

Signed-off-by: Afonso Januário <afonso-januario@hotmail.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Normalize -0.0 in number hashes and test range ends

operator== compares numbers exactly since #5459, so equal numbers
share one value and convert to the same number_float_t. Update the
comment accordingly, map -0.0 to 0.0 before hashing (std::hash need
not do that), and test -0.0 and the ends of the integer ranges. Show
hash(0.0) in the docs example and note the change in the version
history.

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

* Clarify hash documentation after review

- Say "may hash differently" for null, false, and numbers, since a
  collision across types is possible.
- Name the storage types (signed integer, unsigned integer,
  floating-point number) instead of example literals.
- Explain that the hash survives converting an integer to
  number_float_t but not the lossy conversion back, and that unequal
  numbers may share a hash.
- State that the example hash values are illustrative only and vary by
  platform, compiler, compiler version, and library version.

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

---------

Signed-off-by: Afonso Januário <afonso-januario@hotmail.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Afonso Januário <afonso-januario@hotmail.com>
2026-10-07 19:18:51 +02:00
43fe8928e1 Stop binary writers overflowing the stack on deep values (#5781)
* Stop binary writers overflowing the stack on deep values

to_cbor, to_msgpack, and to_ubjson recurse once per nesting level.
The parser is iterative, so a value the library accepts can crash on
the way back out.

Keep the existing recursive path for the first 128 levels and finish
anything deeper on a heap stack. Output is unchanged. BSON is left
alone because its extra size walk is a separate change.

Rebased onto the value-type output sink. The heap frames now initialize
every member, which is what -Weffc++ was rejecting.

See #5392.

Signed-off-by: ayush-singh-0601 <singhayush062006@gmail.com>
(cherry picked from commit cf65ac438f)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Redesign the iterative binary writers around a shared recursion depth limit

Address the open review on the non-recursive CBOR/MessagePack/UBJSON/BJData
writers (#5518):

- Delete the CBOR array/object prefix helpers; both the recursive and
  iterative paths call write_cbor_head(), which already existed on develop.
- MessagePack: share one write_msgpack_array_prefix()/write_msgpack_object_prefix()
  helper per container kind between the recursive and iterative paths, both
  going through to_msgpack_length() so an over-long container throws
  out_of_range.412 identically either way.
- Reuse detail::recursion_depth_limit() instead of a separate constant, the
  same bound serializer::dump() and write_bson_document() already use.
- Redesign the frames after bson_frame/dump_frame: only a container with
  elements is ever pushed, its header is written at the point it is pushed,
  and the iterator is set in the frame's constructor instead of a
  default-then-assign two-step with a since-removed "started" flag. The
  UBJSON frame keeps only the value pointer, the per-element prefix_required
  flag, and the iterator; write_closer and is_object are no longer stored,
  since the former is always !use_count (use_count is constant for the whole
  document) and the latter follows from value->is_object().
- Factor the BJData ND-array shape check into is_bjdata_ndarray(), used by
  both the recursive object case and the iterative pushing logic.
- Give the frame classes the GCC -Weffc++ treatment already used for
  diff_frame: a noexcept converting constructor plus the five special members
  defaulted with no explicit noexcept.
- Fix two @ref self-references in write_cbor/write_msgpack/write_ubjson's own
  doc comments to point at the public to_cbor/to_msgpack/to_ubjson/to_bjdata
  API instead.
- The iterative object-key write for CBOR/MessagePack now runs the same
  strict-mode check_utf8() against the parent object as diagnostics context
  that the recursive path already ran, so the two paths raise identical
  diagnostics across the switch-over.
- Rewrite the tests: round trips instead of a bare size check, byte-exact
  comparisons against the recursive output at depths around the bound, a
  deep object and a BJData ND-array past the bound, a deep discarded value
  (type_error.321), and the OSS-Fuzz 566583014 CBOR/MessagePack regression.

BSON is unaffected by this change; it already walks its documents
iteratively and is covered separately by #5553.

Co-authored-by: ayush-singh-0601 <179524189+ayush-singh-0601@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: ayush-singh-0601 <singhayush062006@gmail.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: ayush-singh-0601 <singhayush062006@gmail.com>
Co-authored-by: ayush-singh-0601 <179524189+ayush-singh-0601@users.noreply.github.com>
2026-10-07 19:18:20 +02:00
Niels Lohmann 3c465beb61 Add tests for error_handler_t::keep in dump() (#4555)
Squashed onto develop from:
- Add error_handler_t::keep to copy invalid UTF-8 bytes unchanged
- Mention error_handler_t::keep in the README

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 19:17:57 +02:00
Niels LohmannandMihnea Magheru e752688b52 Add a natvis fallback visualizer for detail::json_default_base (#5588)
* Add a natvis fallback visualizer for detail::json_default_base

Squashed onto develop from:
- Add a type in the natvis template for detail::json_default_base
- Document the json_default_base natvis fallback and regenerate natvis
- Match json_default_base in both its current and 3.12.0 namespace

Co-authored-by: Mihnea Magheru <sakuntalle@yahoo.com>
Signed-off-by: Mihnea Magheru <sakuntalle@yahoo.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Take the natvis template from the PR in the amalgamation check

The check ran generate_natvis.py from a develop checkout, which loads
nlohmann_json.natvis.j2 from its own directory. A PR that changes the
template was therefore checked against develop's template and always
failed. Copy the PR's template next to the develop script before
running it.

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

---------

Signed-off-by: Mihnea Magheru <sakuntalle@yahoo.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Mihnea Magheru <sakuntalle@yahoo.com>
2026-10-07 19:17:41 +02:00
Niels Lohmann 069ace74af Round-trip BJData ND-array annotations exactly (single precision, key order) (#5707)
Squashed onto develop from:
- Round-trip BJData ND-array annotations exactly (single precision, key order)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 19:17:18 +02:00
Niels Lohmann c6ee5a64be Add editable json_documents: set, push_back, insert, and erase
basic_json_document gets a second template parameter, Editable
(false by default), plus the aliases json_editable_document,
json_editable_view, ordered_json_editable_document and
ordered_json_editable_view.

Editable documents can change values and structure without
rewriting the source text: set()/push_back() on values, keys,
array indices and JSON pointers; insert() before an array
element; erase() of an object key, array index or JSON pointer.

New values and element sequences go into edit storage that the
document owns and never moves, so views keep referring to their
value across edits and a parsed node never moves. Read-only
documents walk the plain node array and are unaffected.

Strings are checked for UTF-8 on entry, so dump() of an editable
document never throws type_error.316. Binary values cannot be
stored (type_error.319).

A seeded differential test applies random edits to an editable
document and to the equivalent ordered_json and compares both
after every step.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:42:38 +02:00
Niels Lohmann 8daec2b596 Scan json_view strings with SIMD and index large objects
Speed up json_view's parser with SIMD scanning and a hash table
for large objects.

Long runs of string bytes are scanned 16 bytes at a time with NEON
(AArch64, GCC and Clang) and SSE2 (x86-64), both baseline
instruction sets. Keys keep 16 table checks before the vector
loop, because their lengths repeat from record to record; string
values get 8, because their lengths vary more. Non-ASCII text is
validated 16 bytes at a time with simdjson's "lookup4" check
(Keiser and Lemire, 2021), with NEON on AArch64 and, on x86-64,
with SSSE3. SSSE3 is not part of baseline x86-64, so the check is
compiled for SSSE3 with a function attribute and used only where
CPUID reports it, which all x86-64 CPUs since about 2011 do; the
answer is cached in a statically initialized atomic, so there is
no guard of a local static and no global constructor. The same
input is accepted either way. JSON_VIEW_NO_SIMD selects the
portable code.

On x86-64, string runs are now checked vector-first: one SSE2
compare from the first byte finds the end of most keys and short
values, instead of a branch per byte for the first 8-16 bytes.
AArch64 keeps the byte-wise steps, where a NEON mask costs more and
the branches predict well. Entering an object or array no longer
stalls: open() stores the parent's frame field by field instead of
building it on the stack and reading it back with wider loads,
which waited for the narrower stores to retire.

Objects with 128 members or more get an open-addressing hash table
built when the object closes, so operator[], at(), find(),
contains(), count(), value(), and JSON pointers take constant time
on average in such objects; of duplicate keys, the first is kept,
as for the linear search. The idea comes from Boost.JSON.

simdjson is credited in simd.hpp's SPDX block, the README, and
license.md.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:42:32 +02:00
Niels Lohmann da1ca7f9d7 Add dump() and comparisons to json_view
Add basic_json_view::dump() and the comparison operators, and read
floats from the parser's digit layout instead of rescanning the
token.

dump(indent, indent_char, ensure_ascii, number_format) writes a
value the way ordered_json::parse(text).dump() writes it for the
same arguments: members in document order, all of them should a
key occur more than once; strings escaped by the same rules, using
the library's scanning kernels; floats written with the library's
to_chars conversion, so the output equals basic_json's byte for
byte; integers copied from the source, where they are already
canonical, except -0, which parse() reads as 0. There is no
error_handler argument, because the view only holds valid UTF-8.
number_format::source copies numbers exactly as they appear in the
source (e.g. "1.50", "1E2", "-0"), which basic_json cannot provide.
operator<< takes the indentation from the stream width, as for
basic_json. The writer walks iteratively, so nesting depth is
limited by memory only.

operator== and operator!= compare two views, or a view and a
basic_json value in either order, by the rules basic_json's
operator== uses: numbers compare by value across their types,
objects compare by their members with duplicate keys resolved as
parse() resolves them, member order matters only where the object
type keeps one, and discarded views compare as discarded basic_json
values do, including under JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.
Nothing is materialized except single scalars.

While parsing, the view now records where the integer digits, the
fraction digits, and the exponent of a float token are, so floats
and doubles with at most 19 digits are read from that layout with
the library's decimal_to_float() instead of rescanning the token.
Both round correctly, so the values are those of parse(). get<double>(),
materialize(), dump(), and the comparisons all use it.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:42:29 +02:00
Niels Lohmann 77acd4563c Add element access, iteration, values, and JSON pointers to json_view
Give basic_json_view the read-only access functions of basic_json:
operator[] and at() with keys and indices, front()/back(), find(),
contains(), count(), begin()/end() and cbegin()/cend(), items()
with structured bindings from C++17 on, and type_name().

Exceptions have the ids and messages of the const functions of
basic_json. Where basic_json has undefined behavior the view
answers safely: operator[] with a missing key or an out-of-range
index returns a discarded view, and front()/back() of an empty
container throw invalid_iterator.214. Objects are iterated in
document order, and all members are visited; duplicate-key lookups
find the first member (as yyjson and simdjson do), while parse(),
materialize(), and the map conversions keep the last value, as
parse() does. Keys of up to 16 bytes are compared with two
overlapping loads.

Add value conversions: get<T>()/get_to() for arithmetic types,
bool, nullptr_t, strings (std::basic_string copied,
string_view_t without a copy), BasicJsonType, views, std::vector,
and maps with string keys; get_string() for the string without a
copy; number_token() for the number exactly as written in the
source; value() with keys and JSON pointers; and operator[]/at()/
contains() with JSON pointers. Everything else, including types
with from_json(), goes through materialize() of that subtree.
get<T>() of arithmetic types is inlined down to the conversion, so
reading an integer needs no call.

detail::json_pointer_access exposes a pointer's reference tokens
to code outside basic_json.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:42:26 +02:00
Niels Lohmann 759dd2e1b1 Add json_document and json_view: node index, parser, and document
Add json_document and json_view, a read-only, zero-copy index of a
JSON text, as the first public slice of the zero-copy view (#5295).

A parse produces a flat array of 16-byte nodes in document order,
one per value and one per object key. Strings stay in the source
text; escaped strings are decoded into an arena. Integers are
converted while their digits are in the cache; floats keep only
their digit layout and are converted on read. Containers store the
size of their subtree, so a reader can step over one in constant
time. A document makes a handful of allocations, however many
values it has.

The parser accepts exactly what json::parse accepts, with every
combination of ignore_comments and ignore_trailing_commas, with and
without a trailing NUL, and under JSON_STRICT_NUL_HANDLING. It is
portable C++11 and does not depend on byte order.

basic_json_document adds parse, parse_copy, accept, read (reuses a
document's memory), root, is_discarded, source, owns_source,
node_count, memory_usage, and shrink_to_fit. basic_json_view adds
type, the is_* queries, operator bool, size, empty, materialize,
and source_offset. A parse error throws the same exception
basic_json::parse would throw for the same input, message and
position included.

detail::abi_config keeps JSON_STRICT_NUL_HANDLING and
JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON readable after json.hpp
undefines them, in the ABI namespace so they always match the
basic_json in use.

A NUL byte that ends a // comment is the end of the input, as in
parse() since #5696.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:42:22 +02:00
Niels Lohmann bfa4886f0f Write doubles with the shortest digits (Żmij), digits in registers
Write doubles with the conversion of Zmij by Victor Zverovich (MIT),
ported to C++11 (detail/conversions/zmij.hpp). It finds the
shortest decimal that reads back as the same double, and the
closest one if there are several. Grisu2, used until now, is fast
but not always shortest: it sometimes writes a 17th digit where 16
suffice, or a last digit that is not the closest. The layout is
unchanged (1.5, 100.0, 1e+100, -0.0); float keeps Grisu2.

Digits are converted eight at a time with the BCD conversion of
Xiang JunBo, as in Zmij, and written with one byte swap per eight
digits and fixed-size moves instead of per-digit loops. Leading and
trailing zeros are counted from those bytes. to_chars() uses a
local buffer when the caller's is shorter than the 41 bytes this
may write. The powers of ten come from the number-parsing table,
adjusted where it holds values rounded up, and extended with Zmij's
compressed tables beyond 10^308.

write_shortest() converts its 16 digits in one vector register
(SSE2 on x86-64, NEON on 64-bit Arm, both baseline) and inserts the
decimal point inside the register, avoiding a store-forwarding
stall that cost about 25% of the time to write a double. dump()
writes floats and integers straight into the serializer's write
buffer instead of copying them from a member buffer, and small
integers eight digits at a time. read_eight_bytes() and
parse_eight_digits() are marked always-inline, which GCC had been
calling out of line in the number-parsing loops.

Of one million random doubles, about 0.14% are now written with
different digits, always to a value that still reads back as the
same double.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:41:47 +02:00
Niels Lohmann 68d61b6aef Speed up the lexer: own float parser, string scan, and \u table
Give the library its own correctly rounded float converter for
binary32 and binary64 (IEEE 754), and speed up the lexer's string
and escape scanning.

The converter splits a number token into sign, significand, and
decimal exponent, then tries Clinger's fast path, then a templated
Eisel-Lemire step, and falls back to an exact big-integer digit
comparison for tokens with more than 19 significant digits whose two
candidate values round differently. This replaces std::from_chars
and strtod/strtof for both formats, so parsed values no longer
depend on the C/C++ library or the current locale. The strtold
fallback kept for other long double formats (x87, binary128) now
also copies a multi-byte decimal point correctly, fixing #5660.
eisel_lemire() and decimal_to_float() are always inlined so callers
keep the whole conversion in their hot loop.

The string-scanning kernels in string_scan.hpp find a stop byte with
the trailing-zero count of the SWAR mask instead of a byte loop, and
scalar_string_bulk_run() validates a run of multi-byte UTF-8
sequences one after another instead of re-searching after each one.

get_codepoint() decodes a contiguous \uXXXX escape with one table
lookup per byte instead of four range-checked get() calls; the
streaming path and all error positions are unchanged.

Adds 508 generated hard float-parsing cases with expected binary32
and binary64 bits, and kernel-comparison tests for the string scans
and the escape table against byte-by-byte references.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:41:43 +02:00
Niels Lohmann 367336c83d Fix CI on develop after #5585 (#5779)
* Fix CI on develop after #5585

- test-diagnostics-optimized: -O3 makes GCC's -Winline and
  -Wsuggest-attribute=pure/const warnings fire with the ci_test_gcc flag
  set; turn them off for this test.
- test-diagnostics-optimized: suppress Clang's -Wexit-time-destructors for
  the static table in to_json.
- Infer: raise pulse-max-disjuncts from 20 to 40. With the default,
  Pulse loses the stored type in basic_json::replace_value() and reports
  false null dereferences of get_ptr() results in unit-pointer_access.cpp.

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

* Ignore Infer's false USE_AFTER_DELETE in ordered_map::erase

Infer's std::string model keeps the buffer of a moved-from string, so the
destroy-and-reconstruct loop in erase(first, last) looks like it destroys a
buffer twice.

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

* Mark throw_on_discarded()'s parameters as used without exceptions

With JSON_NOEXCEPTION, JSON_THROW expands to std::abort(), so Clang's
-Wunused-parameter breaks test-disabled_exceptions (since #5761).

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

* Skip the span_input_adapter sax_parse checks with deleted deprecated functions

The #5676 regression test (#5740) calls the deprecated
sax_parse(span_input_adapter&&, ...), which JSON_DELETE_DEPRECATED_FUNCTIONS
deletes, so ci_test_delete_deprecated_functions failed to build.

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

* Fall back to the first entry in test-diagnostics-optimized's to_json

clang-tidy (clang-analyzer-security.ArrayBound) flagged it->second for a
value not in the table. Use the same fallback as
NLOHMANN_JSON_SERIALIZE_ENUM; the test still fails with -Werror=array-bounds
on the headers from before #5585.

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

* Fix clang-tidy findings in tests from #5762 and #5774

- unit-regression2.cpp (#5762): const/auto for the destroy() test values;
  NOLINT the intended copy in check_destroy_edge_case().
- unit-serialization.cpp (#5774): build the expected strings with += instead
  of chained operator+ (performance-inefficient-string-concatenation).

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:37:19 +02:00
Niels Lohmann 30e542e52a Declare the namespace-scope constants in to_chars.hpp inline (#5776)
MSVC warns with C5260 that kAlpha and kGamma have internal linkage when
the header is used as a header unit or through a module. JSON_INLINE_VARIABLE
makes them inline variables from C++17 on.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 09:03:18 +02:00
Niels Lohmann 24dd7c63f0 Re-amalgamate after #5740 (#5777)
#5740 changed include/nlohmann/json.hpp without regenerating
single_include/nlohmann/json.hpp.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 09:03:17 +02:00
Niels Lohmann e6f32bd28a Stricter fuzzer checks and boundary-value tests for buffers (#5774)
* Check in the fuzzers that parsing without exceptions agrees

Each fuzzer driver now also parses its input with allow_exceptions =
false. That call must never throw a parse_error, must return a discarded
value where parsing with exceptions fails, and must return the same value
where it succeeds. Values are compared by their dump(), because NaN is
not equal to itself.

A plain !is_discarded() assertion, as suggested in #3642, would never
fail: the drivers parse with exceptions, so a result can never be
discarded.

tests/fuzzing.md describes the checks and notes that OSS-Fuzz and
CIFuzz already run LeakSanitizer, because their default address
sanitizer includes it.

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

* Use JSON_HAS_RANGE_VIEW_CONVERSION in the range view regression tests

#5728 combined the JSON_HAS_RANGES and MinGW conditions into
JSON_HAS_RANGE_VIEW_CONVERSION, but three test guards still spelled
them out.

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

* Test the serializer's buffers at their boundaries

The dump() indent overflow survived full line coverage because the tests
grew its buffer by only one step. This adds tests that land exactly on,
and one past, the limits of the other two serializer buffers:

- write_buffer (1024 bytes): strings of 1023, 1024 and 1025 bytes at the
  top level, and of 1022 and 1023 bytes inside an array, so that both
  guards in put_string() are hit at their boundary. Each is checked for
  dump() and for stream output.
- string_buffer (512 bytes, flushed when fewer than 13 bytes remain):
  runs of two-byte escapes, and a surrogate pair written with 14 bytes of
  room, right after a flush, and one escape later.
- The 8-byte bulk scan from the serializer side: 0 to 17 plain bytes
  followed by a quote, a control character, or a non-ASCII character.

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

* Test the chunked string and binary reads of all binary formats

The binary readers read strings and binary values in chunks of 4096
bytes. Only CBOR tested lengths around that size. MessagePack, UBJSON,
BJData and BSON now round-trip lengths 0, 1, 4095, 4096, 4097, 8192 and
100000 from vector and pointer input, and must report a truncated
payload as a parse error.

UBJSON reads binary values as arrays of numbers, so it is tested with
strings only. BJData binary values reach the chunked read only in
Draft 3. BON8 decodes strings byte by byte and does not use this path.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 08:50:12 +02:00
Niels Lohmann e4e7d657ef Document the API stability guarantee in the roadmap (#5775)
* Document what is not covered by the API stability guarantee

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

* Move the API stability guarantee to the roadmap

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

* Note that exceptions to the API stability rules are documented in the release notes

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 08:49:51 +02:00
Niels Lohmann ef570827e3 Point the README's fuzzing badge to the current OSS-Fuzz tracker (#5773)
OSS-Fuzz moved its issues from bugs.chromium.org to issues.oss-fuzz.com.
The old link now redirects to the new tracker but drops the project
filter, so it showed every project's issues.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 07:39:44 +02:00
Niels Lohmann 1c754cfe31 Copy a pair-shaped array value under JSON_BRACE_INIT_COPY_SEMANTICS (#5701)
With JSON_BRACE_INIT_COPY_SEMANTICS enabled, single-element brace
initialization from a JSON value decided whether to copy the value or
build an object by inspecting the value's runtime shape: a two-element
array whose first element is a string, such as ["key", 42], was turned
into an object instead of being copied. This made the behavior depend
on the element's content, and it did not distinguish an existing value
of this shape from a nested braced pair written in the source, such as
the inner {"key", "value"} of {{"key", "value"}}.

json_ref now records whether it was constructed from a braced list
(true only for the std::initializer_list<json_ref> constructor used
for nested braced lists) or from a value. The initializer-list
constructor uses this to copy or move a single non-braced-list element
before deciding whether the list describes an object, so a JSON value
is always copied regardless of its shape, while a braced pair written
in the source still creates an object.

Fixes #5662.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 07:39:05 +02:00
Niels LohmannandJoseph.Demarest ff6f3d7d4a Reject nested indefinite-length CBOR string chunks (#5766)
* fix(cbor): reject nested indefinite string chunks

Signed-off-by: Joseph.Demarest <joseph@demarest.dev>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Address review comments on nested indefinite-length CBOR strings

Rename is_chunk to inside_indefinite, update the stale test section
names, and use lowercase comments like the surrounding code.

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

---------

Signed-off-by: Joseph.Demarest <joseph@demarest.dev>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Joseph.Demarest <joseph@demarest.dev>
2026-10-07 07:38:52 +02:00
Mohd Quamar TyagiandNiels Lohmann 675e519966 Allow SAX parsing of tagged CBOR (#5740)
* Allow SAX parsing of tagged CBOR

Signed-off-by: Tyagiquamar <mohdquamartyagi@gmail.com>

* Consolidate sax_parse overloads with default tag_handler parameter

Signed-off-by: Tyagiquamar <mohdquamartyagi@gmail.com>

* Add version history entry for tag_handler in sax_parse documentation

---------

Signed-off-by: Tyagiquamar <mohdquamartyagi@gmail.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 07:38:24 +02:00
Niels Lohmann 21a69230bd Create a value before giving it its type (#5585)
* Create a value before giving it its type

Squashed onto develop from:
- Create a value before giving it its type
- Skip the failed-allocation test when exceptions are disabled
- Keep the created pointer rather than an uninitialized json_value
- Skip the vector<bool> failed-allocation check for VS 2015 with iterator debugging
- Test the remaining to_json overloads with a failing allocation
- Skip the to_json allocation-failure section on VS 2015 Debug
- Fix false GCC -Warray-bounds error with JSON_DIAGNOSTICS at -O3 (#5744)

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

* Store the new value with a helper in all to_json constructors

Every external_constructor<>::construct now creates the new value first and
hands it to basic_json::replace_value(), which destroys the old value, stores
the new one before setting its type (as elsewhere in this PR), sets the
parents, and checks the invariant.

The std::vector<bool> and std::valarray overloads use array_t's range
constructor, which the other array overloads already rely on. Range views
keep their loop, as begin() and end() of a view may have different types.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-06 22:59:34 +02:00
Niels Lohmannandelix3r 0c2329d0e2 Reduce test suite runtime and run the Unicode tests everywhere (#5605)
Squashed onto develop from:
- Cut Unicode ill-formed byte sweeps to one representative prefix
- Pin unrelated bytes in the remaining ill-formed UTF-8 sweeps
- Speed up unit-unicode1
- Run the cheap binary format size tests unconditionally
- Compile unit-msgpack.cpp only once
- Check the JSON Pointer roundtrip for every code point again
- Cover every byte class in the ill-formed UTF-8 sweeps
- Merge the Unicode tests into unit-unicode.cpp
- Stop excluding the Unicode tests in CI

Signed-off-by: elix3r <157088510+22elix3r@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: elix3r <157088510+22elix3r@users.noreply.github.com>
2026-10-06 22:53:03 +02:00
Niels Lohmann 1a4c9dea73 Fix the standalone release tarball; update compiler list and CITATION (#5734)
Squashed onto develop from:
- Make the json.tar.xz release archive configure standalone
- Update the supported compiler list and the CITATION.cff repository link
- Add json_fwd.hpp to the Bazel singleheader-json target
- Document SwiftPM's #include <json.hpp> form and add CI coverage
- Migrate REUSE metadata from deprecated .reuse/dep5 to REUSE.toml

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-06 22:40:10 +02:00
162e13b86f Add with_*_t alias templates to create basic_json types with changed template parameters (#5758)
* Add helper types to make it easier to create a basic_json type with modified template parameters

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

* Rename with_changed_*_t aliases to with_*_t and merge integer/unsigned aliases

Per review discussion on #3898 between gregmarr and nlohmann:
- rename with_changed_X_t to with_X_t for brevity
- replace the separate with_changed_integer_t/with_changed_unsigned_t
  aliases with a single with_integers_t<NumberIntegerType2, NumberUnsignedType2>
- add @sa doc comment links for the upcoming documentation page

Co-authored-by: Raphael Grimm <1005058+barcode@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Add documentation for the with_*_t member alias templates

Add docs/mkdocs/docs/api/basic_json/with_t.md documenting with_object_t,
with_array_t, with_string_t, with_boolean_t, with_integers_t, with_float_t,
with_allocator_t, with_json_serializer_t, with_binary_t and with_base_class_t,
with an accompanying example, and link the page from the basic_json member
types list and the mkdocs navigation.

Co-authored-by: Raphael Grimm <1005058+barcode@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Add tests for the with_*_t member alias templates

Check with std::is_same that each with_*_t alias produces the expected
basic_json type, and that with_string_t keeps nlohmann::ordered_map as
the object type when used on ordered_json.

Co-authored-by: Raphael Grimm <1005058+barcode@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Fix with_t nav entry and document chaining of the with_*_t aliases

Indent the with_t entry in mkdocs.yml so it is listed under basic_json,
explain that the aliases can be chained and work on ordered_json, and
test both, including json::with_object_t<ordered_map> == ordered_json.

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

* Add docset entry for basic_json::with_t

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: barcode <barcode@example.com>
Co-authored-by: Raphael Grimm <1005058+barcode@users.noreply.github.com>
2026-10-06 22:33:29 +02:00
fhgffy 69874e4544 Fix NUL bytes in UBJSON/BJData high-precision numbers (#5760)
* Fix NUL-terminated UBJSON and BJData high-precision payloads

Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>

* Use English comments for the high-precision NUL fix

Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>

* Track NUL bytes while reading high-precision payloads

Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>

* Drop dates from code comments.

Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>

* Report a NUL in a high-precision number where it is read

Return the parse error from the read loop so the byte offset points at the NUL, and drop the separate check after lexing.

Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>

* Use fixed text for the high-precision NUL error

2026-10-06: Use the known zero byte directly instead of formatting and concatenating it. Preserve the SAX token, error message, and byte offset.
Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>

---------

Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>
2026-10-06 22:30:52 +02:00
dependabot[bot] a7d387a762 Bump mkdocs-htmlproofer-plugin from 1.5.0 to 1.6.0 in /docs/mkdocs (#5771)
Bumps [mkdocs-htmlproofer-plugin](https://github.com/manuzhang/mkdocs-htmlproofer-plugin) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/manuzhang/mkdocs-htmlproofer-plugin/releases)
- [Commits](https://github.com/manuzhang/mkdocs-htmlproofer-plugin/compare/v1.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: mkdocs-htmlproofer-plugin
  dependency-version: 1.6.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-06 22:30:22 +02:00
dependabot[bot] d41887511b Bump source-map-js from 1.2.1 to 1.2.2 in /docs/mkdocs/scripts/mermaid (#5769)
Bumps [source-map-js](https://github.com/7rulnik/source-map-js) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/7rulnik/source-map-js/releases)
- [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/7rulnik/source-map-js/compare/v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: source-map-js
  dependency-version: 1.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-06 22:29:55 +02:00
fhgffy 9b179cee1e Handle all value_t enumerators in has_no_children() (#5770)
2026-10-07: add the scalar enum labels already handled by the default
branch so -Werror=switch-enum builds succeed. Keep the existing behavior
and synchronize the generated single header.

Signed-off-by: fhgffy <102001626+fhgffy@users.noreply.github.com>
2026-10-06 22:29:22 +02:00
Niels Lohmann 6d4543e743 Fix destroy() for ObjectTypes without reverse iteration (#5767)
The non-recursive destroy walk from #5762 picked an object's last child
via object_t::rbegin() and std::prev(end()). Neither is available for
every ObjectType: no_key_compare_map in unit-custom-object-type.cpp has
no rbegin(), so develop no longer compiles that test, and hash maps such
as std::unordered_map only have forward iterators.

The walk can take an object's children in any order, as long as it
finds the same child again while the object is not modified in between.
So objects with bidirectional iterators keep using their last child
(O(1) to remove from vector-based maps like ordered_map), and objects
with forward-only iterators use begin() instead. No reverse iteration
or rbegin() is needed any more, and the walk stays allocation-free.

Adds a forward-only ObjectType to the tests, destroyed both with mixed
nesting and 100000 levels deep.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-06 22:29:13 +02:00
Michiel van SlobbeandMichiel van Slobbe 5ecb704f6b Speedup; check for the expected separator before the lexer's token switch (#5592)
* Check for the expected separator before the lexer's token switch

After a key the parser expects ':', after a value usually ','. Test for
that character first instead of going through scan()'s switch, which
compiles to an indirect jump. Any other character takes the old path,
so tokens and error messages are unchanged.

Parsing 6.3% faster with GCC 15.2 and 2.7% with Clang 22.1 (geomean of
the ParseString, ParseFile and ParseIndented benchmarks).

Signed-off-by: Michiel van Slobbe <michiel.van.slobbe@gmail.com>

* Improvement: address PR comments

Signed-off-by: Michiel van Slobbe <michiel.van.slobbe@gmail.com>

* fix: address comments

Signed-off-by: Michiel van Slobbe <michiel.van.slobbe@gmail.com>

* Fix clang-tidy bugprone-signed-char-misuse in scan_expecting

Convert the expected separator through unsigned char before storing it as
char_int_type. The generated code is unchanged.

Signed-off-by: Michiel van Slobbe <michiel.van.slobbe@gmail.com>

* Use raw string literals in the separator comment tests

Signed-off-by: Michiel van Slobbe <michiel.van.slobbe@gmail.com>

---------

Signed-off-by: Michiel van Slobbe <michiel.van.slobbe@gmail.com>
Co-authored-by: Michiel van Slobbe <michiel.van.slobbe@gmail.com>
2026-10-06 08:36:40 +02:00
Niels Lohmann 0490778fc3 Replace retired macOS 14 runner and test all available Xcode versions (#5757)
* Replace retired macOS 14 runner and test all available Xcode versions

GitHub retires the macos-14 image on 2026-11-02 (brownouts from
2026-10-05). Xcode 15 is not available on any remaining hosted
runner, so drop the macos-14 job and its documented compilers.

Also test the Xcode versions that the images provide but CI did not
use (26.1.1-26.3 on macos-15, 26.4.1-26.6 on a new macos-26 job), and
pin GCC 16 explicitly next to gcc:latest.

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

* Document new Xcode and GCC versions in the supported compilers table

Versions taken from the CI logs of this PR (Xcode 26.1.1-26.6) and
from the gcc:16 image (same digest as gcc:16.2.0 and gcc:latest).

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-06 07:46:24 +02:00
0a365865f9 Make basic_json destruction allocation-free and non-recursive (#5762)
* Use the provided allocator in destroy() (#4842)

Uses the provided allocator to allocate the stack used to avoid
recursion in the destroy() implementation used by ~basic_json.

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

* Test that the destructor uses the provided allocator

Adds a regression test for #4842: destroying a nested array or object must allocate its temporary stack through the basic_json allocator, not std::allocator.

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

* Fix allocation failure during JSON destruction

Signed-off-by: Michael Sam <michaelsam94@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Make json_value::destroy() non-recursive and allocation-free

destroy() used to flatten a nested array/object into a heap-allocated
std::vector to avoid recursing per nesting level. That vector could
itself throw bad_alloc under memory pressure, and since it now used the
basic_json's own allocator (#4842), a failing allocator supplied by the
caller made this more likely, not less. An exception thrown from inside
~basic_json(), which is noexcept, terminates the program (#5135).

Replace the vector-based stack with a pointer-reversal walk that visits
the tree without recursing per level and without allocating anything:
cur is the array/object currently being emptied, prev is its parent
(or null at the top). A parent's last child slot doubles as storage for
that parent's own parent link while we are below it, so no extra memory
is needed. A child is only ever removed once it is a scalar or an empty
array/object, which neither allocates nor recurses more than one level
deep. take() moves m_data between these locals directly, bypassing
set_parents()/assert_invariant() (the former is O(#children) per call
under JSON_DIAGNOSTICS, which would make the walk quadratic otherwise).

This also removes the std::vector<basic_json, allocator_type> stack
added by #4842, so the extra allocations it introduced disappear along
with it.

Co-authored-by: Michael Sam <9461037+michaelsam94@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Test that destroy() performs no allocation, even under memory pressure

Update the #4842 regression test: it used to check that destroying a
nested array/object made at least one allocation through the provided
allocator (the old flattening stack). Now that destroy() does not
allocate at all, assert the opposite: zero allocations, deallocations
only.

Rework the #5135 regression test to use a dedicated failing/counting
allocator instead of overriding the process-wide ::operator new and
::operator delete, which affected every allocation in the whole
unit-regression2 binary rather than just the values under test. Keep
the original small repro as one case, and add deep (100000 levels) and
wide-and-deep nested array/object/ordered_json cases, all destroyed
while every further allocation is made to fail: the destructor must
complete without allocating, without throwing, and without leaking.

Co-authored-by: Michael Sam <9461037+michaelsam94@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Refactor destroy() for readability and add edge-case tests

Apply review feedback from Greg Marr on the json_value::destroy()
non-recursive, allocation-free destruction walk (#5135):

- last_child() now uses object->rbegin()->second instead of
  std::prev(object->end())->second; pop_last_child() keeps
  std::prev(end()) since erase() needs a forward iterator.
- is_empty_container() becomes has_no_children(), a switch that
  returns true for every non-container type as well as empty
  array/object, simplifying the "scalar or already-empty child"
  check at the call site. The local variable `last` is renamed to
  `cur_last_ref` for clarity.
- free_container() asserts the array/object is already empty before
  freeing it, and the object branches assert the expected type.
- destroy(value_t t) is now a thin dispatcher to destroy_string(),
  destroy_binary(), and destroy_container(t), each handling its own
  "not initialized" check and sharing the simple cases first in the
  switch.
- destroy_container() moves the top-level container into the local
  stand-in via a plain swap of the json_value union, instead of a
  manual copy plus clearing array/object by hand.
- The "cur has no children and there is no parent" case now frees
  cur and returns immediately, so the main loop is a plain
  while (true) with no trailing code after it.

Also adds edge-case tests for both json and ordered_json (mixes of
empty/non-empty arrays and objects, container children in first/last
position, single-element chains, top-level empty containers, and
destruction via erase()/assignment), plus a mixed-tree case in the
"destructor performs no allocation" test.

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

* Make the destroy() walk helpers private

They modify basic_json internals without maintaining its invariants and
are only meant for destroy_container(), so they no longer need to be
reachable from the rest of basic_json.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Michael Sam <michaelsam94@users.noreply.github.com>
Co-authored-by: Vesko Karaganev <vesko.karaganev@gmail.com>
Co-authored-by: Michael Sam <michaelsam94@users.noreply.github.com>
Co-authored-by: Michael Sam <9461037+michaelsam94@users.noreply.github.com>
2026-10-06 07:40:39 +02:00
5379e04ce4 Throw type_error.321 when serializing discarded values to binary formats (#5761)
* Throw type_error.321 when serializing discarded values to binary formats

The CBOR, MessagePack, UBJSON, BJData, and BSON writers silently
skipped the payload of a value_t::discarded value nested in an array
or object, while still writing its slot in the element/member count
(and, for BSON, its entry header), producing a binary document whose
declared size does not match what was actually written.

Throw type_error.321 instead, for a discarded value anywhere in the
tree, including at the top level.

Rewritten from the original PR against the current (non-recursive
option aside) binary_writer.hpp, which has changed substantially since
this was first proposed; the out_of_range.412 MessagePack size check
and unrelated test reformatting from that PR are dropped as out of
scope here.

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

* Document and test type_error.321 for discarded binary values

Add docs for the new exception (home/exceptions.md and the Exceptions
sections of to_cbor/to_msgpack/to_ubjson/to_bjdata/to_bson) and test
coverage for a discarded value nested in an array or object, nested
deeper, and (for UBJSON/BJData) inside an optimized same-type array,
for each of CBOR, MessagePack, UBJSON, BJData, and BSON. Adjust the
three pre-existing "discarded" tests that asserted the old silent
behavior (empty/short output) to expect type_error.321 instead.

Co-authored-by: ameliabarnabyhub <312084480+ameliabarnabyhub@users.noreply.github.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: ameliabarnabyhub <ameliabarnabyhub@users.noreply.github.com>
Co-authored-by: ameliabarnabyhub <312084480+ameliabarnabyhub@users.noreply.github.com>
2026-10-06 07:33:34 +02:00
Niels Lohmann 8a142bc436 Fix CI on develop after #5600, #5607, and #5755 (#5764)
* Fix CI on develop after #5600, #5607, and #5755

- binary_reader: cast the result of -1 - number back to number_integer_t,
  because a number_integer_t narrower than int is promoted to int, which
  GCC's -Warith-conversion rejects (ci_test_gcc, ci_test_standards_gcc)
- JSON_DELETE_DEPRECATED_FUNCTIONS: declare the deleted stream operators
  as function templates at namespace scope, because GCC < 5 rejects deleted
  friend functions ("can't initialize friend function") and Clang 7-9 report
  a redefinition when a class template has a deleted friend function
- docs: give the examples of JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS "Example:"
  titles and add the page to the docset (style_check)

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

* Ignore libstdc++'s <format> sign change in the sanitizer job

libstdc++ 14's <format> initializes a size_t parameter with -1 (GCC bug
119429), so every std::format call fails ci_test_clang_sanitizer under
-fsanitize=integer (test-std-format_cpp20). Exclude only the
implicit-integer-sign-change check and only that header via
-fsanitize-ignorelist.

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

* Fix the AppVeyor (MSVC 2015-2019) build

- binary_reader: emit_signed/emit_unsigned pass integers that do not fit
  the number types to emit_float as long double, because MSVC's <cmath>
  has no integer overloads of std::isfinite (C2668 'fpclassify'), from #5607
- scalar comparisons: the friend operators take the JSON type for their
  noexcept from their parameter, because MSVC 2015/2017 take basic_json as
  the class template there (C3203) and MSVC 2019 16.0 does not see member
  types or template parameters, from #5751
- unit-conversions2: skip the !is_nothrow_constructible static_assert for
  std::optional on MSVC 2017, which evaluates the conditional noexcept as
  true (C2607), from #5754

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

* Re-amalgamate

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

* Avoid MSVC 2015's C4800 for enums with underlying type bool

MSVC 2015 warns about any conversion to bool (C4800), even with an
explicit cast, so the enum conversions from #5754 (#5671) failed the
AppVeyor build with /WX. Convert to bool by comparing with zero via the
new detail::bool_aware_static_cast, and keep doctest from printing the
enum in the test.

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

* Skip the #5650 allocator test on MSVC 2015 debug builds

MSVC 2015's debug STL constructs the containers' debug proxies through
the allocator in noexcept constructors, so countdown_allocator's failing
construction crashes test-allocator (SIGSEGV) instead of throwing
std::bad_alloc. Use the guard #5585 uses for the same reason.

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

* Skip deleted-function detection checks on MSVC 2015

MSVC 2015 does not treat selecting a deleted function in decltype as a
substitution failure, so the detection traits in
unit-delete_deprecated_functions (#5755) and the integral-key checks in
unit-element_access2 (#5657) report deleted overloads as callable there.
Calling them still fails to compile. Skip those checks for
_MSC_VER < 1910, and use the stream operators for real in the runtime
section, so MSVC 2015 still compiles them with the macro set.

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

* Split the Visual Studio 2017 AppVeyor jobs in two

The VS 2017 jobs hit AppVeyor's 60-minute limit per job while still
compiling the tests (77 of about 108 test targets after 58 minutes).
They pass /std:c++17 for everything anyway, so build only the C++17
variant of each test (JSON_TestStandards=17), and split the unit test
files across two jobs each with the new JSON_TestShard=<index>/<count>
option, which keeps every <count>-th test file starting at <index>.
The extra variants of single test files are built in shard 0 only.

CMAKE_OPTIONS is no longer quoted in appveyor.yml, so that it can hold
more than one option.

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

* Fix std::terminate when converting std::optional with MSVC 2017

MSVC 2017 evaluates std::is_nothrow_assignable<json&, const T&> as true
even if T's to_json throws, so to_json(json&, const std::optional<T>&)
was noexcept there and the exception from #5642's test called
std::terminate instead of propagating. Make that conversion never
noexcept on MSVC 2017; all other compilers keep the exact condition.
The static_asserts on the condition are skipped for MSVC 2017; the
runtime check that the exception propagates still runs there.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-06 07:22:55 +02:00
Niels Lohmann 23d3b373e1 Add JSON_DELETE_DEPRECATED_FUNCTIONS to delete the deprecated functions (#5755)
* Add JSON_DELETE_DEPRECATED_FUNCTIONS to delete the deprecated functions

Defining JSON_DELETE_DEPRECATED_FUNCTIONS to 1 (or the CMake option
JSON_DeleteDeprecatedFunctions) declares every deprecated function as
deleted instead of deprecated, so that code that is not ready for 4.0.0
no longer compiles. A deleted function still takes part in overload
resolution, so from_*(ptr, len) cannot silently bind len to the strict
parameter of from_*(InputType&&, bool); the roadmap now plans to keep
these overloads deleted in 4.0.0 instead of removing them.

The legacy discarded-value comparison is left to its own macro.

Also update the 4.0 roadmap: add JSON_DISABLE_TUPLE_REFERENCE_CONVERSION
and JSON_DELETE_DEPRECATED_FUNCTIONS to the macro table, add the
from_bjdata/from_bon8 (ptr, len) overloads to the deprecated functions,
document the macro in the migration guide, and fix the docs style check
findings (example titles, missing docset entry for JSON_STRICT_BINARY_UTF8).

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

* Declare each deprecated function once and guard only its body

Instead of repeating every deprecated declaration in an
#if JSON_DELETE_DEPRECATED_FUNCTIONS branch, keep one declaration
(with its deprecation attribute) and switch only between "= delete;"
and the function body. Suggested by @gregmarr in the review.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-04 22:11:34 +02:00
Niels Lohmann c5a7a4b46d Add deprecated from_bon8/from_bjdata(ptr, len) overloads (#5688)
from_bon8(ptr, len) and from_bjdata(ptr, len) had no overload for a
pointer and a length, unlike from_cbor/from_msgpack/from_ubjson/
from_bson. The call instead bound to from_*(InputType&&, bool strict),
which read ptr as a NUL-terminated C string via strlen and silently
converted len to the strict flag. Data containing a 0x00 byte was cut
off there; data without one was read past the end of the buffer.

Add a deprecated (ptr, len, strict, allow_exceptions) overload for
each function that forwards to (ptr, ptr + len, ...), matching the
existing deprecated overloads of the other four binary readers. Since
neither function ever had this overload, the deprecation is declared
as of version 3.13.0, the next unreleased version, rather than the
version each function was originally added in.

Fixes #5648.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-04 22:11:34 +02:00
Niels Lohmann 4f69be80d6 Clarify wording in diff documentation (#5759)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-04 18:20:20 +02:00
Niels LohmannandMuhammad Amir bin Mohamad Ghazaly 8c1f60a45e Store maps with enum keys as objects (opt-in) (#5600)
* Store maps with enum keys as objects (opt-in)

Maps with enum keys, such as std::map<E, T>, are stored as arrays of
[key, value] pairs, because enums are not convertible to the string type
of object keys - even if NLOHMANN_JSON_SERIALIZE_ENUM maps them to
strings (#4378).

The new JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS macro stores them as objects
instead, converting each key with the enum's to_json. It applies to any
map-like type with enum keys (std::map with any comparator,
std::unordered_map, ...). A key that does not convert to a string throws
type_error.302, and two keys converting to the same string throw the new
type_error.318, rather than losing an entry. The macro changes the output
of inline functions, so it is part of the ABI tag (_ekmo).

Reading needs no macro: std::map and std::unordered_map with enum keys
are now also read from objects, converting each key with the enum's
from_json. That input was rejected before, and arrays of pairs are still
read, so data written either way can be read.

This supersedes #4531, which first proposed storing these maps as
objects.

Co-authored-by: Muhammad Amir bin Mohamad Ghazaly <amirghaz@umich.edu>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Keep multimaps with enum keys as arrays of pairs

With JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, is_enum_keyed_map also matched
std::multimap and std::unordered_multimap. Storing them as objects throws
type_error.318 as soon as a key occurs twice, which is the normal case for
a multimap, so such values could no longer be serialized at all once the
macro was enabled, although they are stored losslessly as arrays of
[key, value] pairs without it.

Exclude maps with non-unique keys from is_enum_keyed_map. They are
detected by insert(value_type) returning an iterator rather than a
pair<iterator, bool>. Map-like types without such an insert() are still
treated as before.

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

* Move the default enum-keyed map tests out of unit-conversions.cpp

The Windows clang 20.1.8 job (MinGW, Debug) failed to link
test-conversions_cpp17 with "relocation truncated to fit:
IMAGE_REL_AMD64_REL32 against .rdata": the object file of
unit-conversions.cpp was already close to the limit, and the new
"maps with enum keys" test case pushed it over. windows.yml asks to keep
these objects small by splitting test files.

Move the test case unchanged into unit-enum_keyed_maps_default.cpp,
with the three enums it needs. It still honors a -D flag for
JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, as before. unit-conversions.cpp
is back to its state on develop.

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

* Build the enum-keyed map test object instead of parsing it

ci_test_diagnostic_positions failed in unit-enum_keyed_maps_default.cpp:
with JSON_DIAGNOSTIC_POSITIONS, a parsed value adds its byte range to
the exception message ("(bytes 0-7) type must be array, but is
object"), so the exact-message checks did not match. Build the object
in memory, like unit-custom-array-type.cpp does.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Muhammad Amir bin Mohamad Ghazaly <amirghaz@umich.edu>
2026-10-04 17:54:05 +02:00
Niels Lohmann 6b4b825af2 Handle numbers that do not fit narrow number types in the binary readers (#5607)
* Handle numbers that do not fit narrow number types in the binary readers

With custom number types narrower than the values in a binary document,
for example basic_json<..., std::int32_t, std::uint32_t, float>, every
binary reader (CBOR, MessagePack, UBJSON, BJData, BSON, BON8) passed the
decoded number to the SAX interface with an implicit conversion: the
integer 5000000000 silently became 705032704, and a finite double such as
1e300 became infinity. The lexer handles the same values in JSON text: an
integer that fits neither integer type is stored as number_float_t, and a
finite number that overflows number_float_t is rejected with
out_of_range.406.

Pass every number read from binary input through three helpers that
apply the lexer's rules:
- emit_signed(): number_integer_t, else number_unsigned_t for a
  non-negative value, else number_float_t
- emit_unsigned(): number_unsigned_t, else number_float_t
- emit_float(): out_of_range.406 if a finite value overflows
  number_float_t; infinity and NaN are passed on

For consistency, a CBOR negative integer below the range of
number_integer_t is now stored as number_float_t, like a too small
integer in JSON text, instead of being rejected with parse_error.112.
With the default number types, this is the only change in behavior.

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

* Fix MSVC and clang 3.5 in the narrow number type test

MSVC types 3000000000 and 5000000000 as unsigned long, so
json(-3000000000) triggered C4146 (unary minus on an unsigned type),
which /WX turns into an error. Use LL literals, as elsewhere in the
tests.

clang 3.5 cannot convert the lambdas in the braced initializer of the
format table to function pointers. Use named functions instead.

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

* Check integer-to-float fallbacks for overflow in the binary readers

emit_signed, emit_unsigned, and the CBOR negative integer fallback now
pass their number_float_t fallback through emit_float, so a value that
overflows number_float_t is rejected with out_of_range.406 like a
floating-point value, instead of silently becoming infinity. This only
matters for a number_float_t that cannot represent 2^64, such as a
half-precision type. The CBOR value -1 - n is computed as long double so
that emit_float sees a finite value.

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

* Use the input_format member instead of passing the format to binary_reader helpers

The helpers (get_number, get_to, get_string, get_binary, get_bytes,
emit_signed, emit_unsigned, emit_float, unexpect_eof, exception_message)
are members of binary_reader, which already stores the format it was
constructed with, so the parameter was redundant.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-04 17:53:29 +02:00
424 changed files with 68984 additions and 5155 deletions

No files matched your search

+3
View File
@@ -205,6 +205,9 @@ API of the 3.x.y version is broken. This includes:
- Changing access specifiers.
- Changing default arguments.
What is and is not covered by this guarantee is described in the
[roadmap](https://json.nlohmann.me/community/roadmap/#api-stability).
Although these guidelines may seem restrictive, they are essential for maintaining the library’s utility.
Breaking changes may be introduced when they are guarded with a feature macro such as
+19 -9
View File
@@ -16,6 +16,9 @@ only_commits:
environment:
matrix:
# The Visual Studio 2017 jobs compile everything with /std:c++17, so they
# only build the C++17 variant of each test, split into two jobs each to
# stay below AppVeyor's 60-minute limit per job.
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
configuration: Debug
platform: x86
@@ -34,7 +37,13 @@ environment:
configuration: Release
platform: x86
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
CMAKE_OPTIONS: ""
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2"
GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
configuration: Release
platform: x86
CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX"
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2"
GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
@@ -55,7 +64,13 @@ environment:
configuration: Release
platform: x64
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
CMAKE_OPTIONS: ""
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2"
GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
configuration: Release
platform: x64
CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX"
CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2"
GENERATOR: Visual Studio 15 2017
init:
@@ -66,15 +81,10 @@ install:
- if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32
before_build:
- cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On "%CMAKE_OPTIONS%"
- cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On %CMAKE_OPTIONS%
build_script:
- cmake --build . --config "%configuration%" --parallel 2
test_script:
- if "%configuration%"=="Release" ctest -C "%configuration%" --parallel 2 --output-on-failure
# On Debug builds, skip test-unicode_all
# as it is extremely slow to run and cause
# occasional timeouts on AppVeyor.
# More info: https://github.com/nlohmann/json/pull/1570
- if "%configuration%"=="Debug" ctest --exclude-regex "test-unicode" -C "%configuration%" --parallel 2 --output-on-failure
- ctest -C "%configuration%" --parallel 2 --output-on-failure
+17
View File
@@ -45,6 +45,23 @@ 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_(editable_)?(document|view)\\.md"
- "docs/mkdocs/docs/examples/(basic_json_(document|view)__|(ordered_)?json_(editable_)?(document|view)).*"
- "tests/benchmarks/src/benchmarks_view\\.cpp"
- label: "aspect: json_view"
title: "(?i)(json_view|json_document|zero-copy)"
- label: "python"
files:
- "\\.py$"
+11 -1
View File
@@ -118,12 +118,15 @@ 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 .
cp include/nlohmann/json_literals.hpp $INCLUDE_DIR/json_literals.hpp
# 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.hpp $INCLUDE_DIR/json_fwd.hpp $INCLUDE_DIR/json_view.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
@@ -149,6 +152,13 @@ jobs:
VERSION_MAJOR=$(grep -m1 'define NLOHMANN_JSON_VERSION_MAJOR' $ABI_MACROS | grep -o '[0-9]\+')
VERSION_MINOR=$(grep -m1 'define NLOHMANN_JSON_VERSION_MINOR' $ABI_MACROS | grep -o '[0-9]\+')
VERSION_PATCH=$(grep -m1 'define NLOHMANN_JSON_VERSION_PATCH' $ABI_MACROS | grep -o '[0-9]\+')
# The template is what this check verifies the committed natvis
# file against, so take it from this PR rather than from the
# develop checkout: generate_natvis.py loads the template from its
# own directory, and with develop's copy a PR that changes the
# template could never pass. Like the macro_builder step above,
# this only renders PR content in a job without credentials.
cp tools/generate_natvis/nlohmann_json.natvis.j2 $NATVIS_TOOL_DIR/
python3 $NATVIS_TOOL_DIR/generate_natvis.py --version "$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH" $MAIN_DIR
- name: Build patch and check for differences
+41 -6
View File
@@ -17,11 +17,11 @@ permissions:
contents: read
jobs:
macos-14:
runs-on: macos-14 # https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md
macos-15:
runs-on: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
strategy:
matrix:
xcode: ['15.0.1', '15.1', '15.2', '15.3', '15.4']
xcode: ['16.0', '16.1', '16.2', '16.3', '16.4', '26.0.1', '26.1.1', '26.2', '26.3']
env:
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
@@ -36,11 +36,11 @@ jobs:
- name: Test
run: cd build ; ctest -j 10 --output-on-failure
macos-15:
runs-on: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
macos-26:
runs-on: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
strategy:
matrix:
xcode: ['16.0', '16.1', '16.2', '16.3', '16.4', '26.0.1']
xcode: ['26.4.1', '26.5', '26.6']
env:
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
@@ -71,3 +71,38 @@ jobs:
run: cmake --build build --parallel 10
- name: Test
run: cd build ; ctest -j 10 --output-on-failure
swiftpm:
runs-on: macos-15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Check that Package.swift resolves without a deprecation warning
run: swift package dump-package
- name: Build the SwiftPM documentation example against this checkout
run: |
mkdir -p /tmp/json-swiftpm-consumer/Sources/MyLibrary
cp docs/mkdocs/docs/integration/swift/example.cpp /tmp/json-swiftpm-consumer/Sources/MyLibrary/example.cpp
cat > /tmp/json-swiftpm-consumer/Package.swift << EOF
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyPackage",
dependencies: [
.package(path: "${{ github.workspace }}")
],
targets: [
.target(
name: "MyLibrary",
dependencies: [
.product(name: "json", package: "json")
],
publicHeadersPath: "."
)
]
)
EOF
cd /tmp/json-swiftpm-consumer
swift build
+47 -2
View File
@@ -31,6 +31,51 @@ jobs:
- name: Build
run: cmake --build build --target ci_test_gcc
ci_meson_install:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
- name: Check that Meson and pkg-config offer the CMake options
run: make check_build_options
- name: Install Meson
run: pip install meson
- name: Install with Meson
run: |
meson setup build-meson --prefix=${{ github.workspace }}/install
meson install -C build-meson
- name: Use the installed package with find_package
run: |
cmake -S tests/cmake_import/project -B build-import -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install
cmake --build build-import
- name: Install with Meson and non-default options
run: |
meson setup build-meson-options --prefix=${{ github.workspace }}/install-options -DMultipleHeaders=true -DDiagnostics=true -DGlobalUDLs=false -DDisableTupleReferenceConversion=true -DStrictBinaryUTF8=true -DDeleteDeprecatedFunctions=true
meson install -C build-meson-options
- name: Check that the options reach the installed files
run: |
test -d install-options/include/nlohmann/detail
cflags=$(PKG_CONFIG_PATH=${{ github.workspace }}/install-options/share/pkgconfig pkg-config --cflags nlohmann_json)
echo "$cflags"
echo "$cflags" | grep -q -- '-DJSON_DIAGNOSTICS=1'
echo "$cflags" | grep -q -- '-DJSON_USE_GLOBAL_UDLS=0'
echo "$cflags" | grep -q -- '-DJSON_DISABLE_TUPLE_REFERENCE_CONVERSION=1'
echo "$cflags" | grep -q -- '-DJSON_STRICT_BINARY_UTF8=1'
echo "$cflags" | grep -q -- '-DJSON_DELETE_DEPRECATED_FUNCTIONS=1'
grep -q 'JSON_USE_GLOBAL_UDLS=0;JSON_DISABLE_TUPLE_REFERENCE_CONVERSION=1;JSON_DIAGNOSTICS=1' install-options/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake
grep -q 'JSON_STRICT_BINARY_UTF8=1;JSON_DELETE_DEPRECATED_FUNCTIONS=1' install-options/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake
cmake -S tests/cmake_import/project -B build-import-options -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install-options
cmake --build build-import-options
- name: Install with Meson and the include directory outside the prefix
run: |
meson setup build-meson-split --prefix=${{ github.workspace }}/install-split --includedir=${{ github.workspace }}/install-split-dev/include
meson install -C build-meson-split
cmake -S tests/cmake_import/project -B build-import-split -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install-split
cmake --build build-import-split
ci_infer:
runs-on: ubuntu-latest
steps:
@@ -107,7 +152,7 @@ jobs:
container: ubuntu:24.04
strategy:
matrix:
target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_no_thread_local]
target: [ci_cmake_flags, ci_test_diagnostics, ci_test_diagnostic_positions, ci_test_noexceptions, ci_test_noimplicitconversions, ci_test_legacycomparison, ci_test_noglobaludls, ci_test_disableenumserialization, ci_test_disabletuplereferenceconversion, ci_test_skiplibraryversioncheck, ci_test_simdutf, ci_test_strict_nul_handling, ci_test_delete_deprecated_functions, ci_test_no_thread_local]
steps:
- name: Install build-essential
run: apt-get update ; apt-get install -y build-essential unzip wget git
@@ -209,7 +254,7 @@ jobs:
strategy:
matrix:
# older GCC docker images (4, 5, 6) fail to check out code
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', 'latest']
compiler: ['7', '8', '9', '10', '11', '12', '13', '14', '15', '16', 'latest']
container: gcc:${{ matrix.compiler }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+2 -2
View File
@@ -178,7 +178,7 @@ jobs:
- name: Build
run: cmake --build build --parallel 10
- name: Test
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
run: cd build ; ctest -j 10 -C Debug --output-on-failure
clang-cl-12:
runs-on: windows-2022
@@ -195,7 +195,7 @@ jobs:
- name: Build
run: cmake --build build --config Debug --parallel 10
- name: Test
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
run: cd build ; ctest -j 10 -C Debug --output-on-failure
ci_module_cpp20:
runs-on: windows-2022
+2
View File
@@ -1,5 +1,7 @@
{
"_comment": "Used by the ci_infer CMake target (#5715 item 4b). fail-on-issue makes CI fail on Infer findings; disable-issue-type is a type-level baseline for the ~174 pre-existing findings (all PULSE_UNNECESSARY_COPY*/PULSE_RESOURCE_LEAK/PULSE_CONST_REFABLE, mostly in test code) triaged in run https://github.com/nlohmann/json/actions/runs/35829411620 on commit 1054b2097, so CI fails only on a NEW issue type. Remove an entry here once its findings have been fixed or explicitly accepted.",
"_comment_pulse": "Pulse stops exploring paths after pulse-max-disjuncts (default 20). With the default, basic_json::replace_value() (destroy + assert_invariant) exceeds the limit, Pulse loses the stored type, and reports false NULLPTR_DEREFERENCE findings for get_ptr() results in tests/src/unit-pointer_access.cpp.",
"pulse-max-disjuncts": 40,
"fail-on-issue": true,
"disable-issue-type": [
"PULSE_UNNECESSARY_COPY_ASSIGNMENT",
-36
View File
@@ -1,36 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: json
Upstream-Contact: Niels Lohmann <mail@nlohmann.me>
Source: https://github.com/nlohmann/json
Files: *
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me>
License: MIT
Files: include/nlohmann/thirdparty/hedley.hpp
Copyright: 2016-2021 Evan Nemerson <evan@nemerson.com>
License: CC0
Files: include/nlohmann/detail/meta/cpp_future.hpp
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors
License: MIT AND Apache-2.0
Files: tests/thirdparty/doctest/*
Copyright: 2016-2023 Viktor Kirilov
License: MIT
Files: tests/thirdparty/fifo_map/*
Copyright: 2015-2017 Niels Lohmann
License: MIT
Files: tests/thirdparty/imapdl/*
Copyright: 2017 Georg Sauthoff <mail@gms.tf>
License: GPL-3.0-only
Files: tools/amalgamate/*
Copyright: 2012 Erik Edlund <erik.edlund@32767.se>
License: BSD-3-Clause
Files: tools/gdb_pretty_printer/*
Copyright: 2020 Hannes Domani <https://github.com/ssbssa>
License: MIT
+26
View File
@@ -20,11 +20,13 @@ 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",
"include/nlohmann/detail/conversions/to_chars.hpp",
"include/nlohmann/detail/conversions/to_json.hpp",
"include/nlohmann/detail/conversions/zmij.hpp",
"include/nlohmann/detail/exceptions.hpp",
"include/nlohmann/detail/hash.hpp",
"include/nlohmann/detail/input/binary_reader.hpp",
@@ -65,9 +67,31 @@ 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/compare.hpp",
"include/nlohmann/detail/view/document_data.hpp",
"include/nlohmann/detail/view/edit.hpp",
"include/nlohmann/detail/view/edit_storage.hpp",
"include/nlohmann/detail/view/errors.hpp",
"include/nlohmann/detail/view/input.hpp",
"include/nlohmann/detail/view/iterator.hpp",
"include/nlohmann/detail/view/lookup.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/object_index.hpp",
"include/nlohmann/detail/view/pointer.hpp",
"include/nlohmann/detail/view/scan.hpp",
"include/nlohmann/detail/view/serializer.hpp",
"include/nlohmann/detail/view/simd.hpp",
"include/nlohmann/detail/view/string_ref.hpp",
"include/nlohmann/detail/view/value.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",
@@ -80,6 +104,8 @@ cc_library(
name = "singleheader-json",
hdrs = [
"single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp",
"single_include/nlohmann/json_view.hpp",
],
includes = ["single_include"],
visibility = ["//visibility:public"],
+1 -1
View File
@@ -10,5 +10,5 @@ title: "JSON for Modern C++"
version: 3.12.0
date-released: 2025-04-07
license: MIT
repository-code: "https://github.com/nlohmann"
repository-code: "https://github.com/nlohmann/json"
url: https://json.nlohmann.me
+43 -2
View File
@@ -42,8 +42,11 @@ endif()
## OPTIONS
##
# Build the tests by default only for the main project and only if the tests
# directory exists (the release archive json.tar.xz does not contain it).
# VERSION_GREATER_EQUAL is not available in older CMake (< 3.7)
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13))
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13)
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
set(JSON_BuildTests_INIT ON)
else()
set(JSON_BuildTests_INIT OFF)
@@ -62,6 +65,7 @@ option(JSON_MultipleHeaders "Use non-amalgamated version of the l
option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF)
option(JSON_StrictNulHandling "Build with strict NUL-byte handling enabled." OFF)
option(JSON_StrictBinaryUTF8 "Build with UTF-8 checks in the CBOR, UBJSON, BJData, and BSON writers enabled." OFF)
option(JSON_DeleteDeprecatedFunctions "Delete the deprecated functions instead of only deprecating them." OFF)
if (JSON_CI)
include(ci)
@@ -123,6 +127,10 @@ if (JSON_StrictBinaryUTF8)
message(STATUS "Strict UTF-8 checks in binary writers enabled (JSON_STRICT_BINARY_UTF8=1)")
endif()
if (JSON_DeleteDeprecatedFunctions)
message(STATUS "Deprecated functions are deleted (JSON_DELETE_DEPRECATED_FUNCTIONS=1)")
endif()
if (JSON_Diagnostic_Positions)
message(STATUS "Diagnostic positions enabled (JSON_DIAGNOSTIC_POSITIONS=1)")
endif()
@@ -159,6 +167,7 @@ target_compile_definitions(
$<$<BOOL:${JSON_LegacyDiscardedValueComparison}>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>
$<$<BOOL:${JSON_StrictNulHandling}>:JSON_STRICT_NUL_HANDLING=1>
$<$<BOOL:${JSON_StrictBinaryUTF8}>:JSON_STRICT_BINARY_UTF8=1>
$<$<BOOL:${JSON_DeleteDeprecatedFunctions}>:JSON_DELETE_DEPRECATED_FUNCTIONS=1>
)
target_include_directories(
@@ -180,7 +189,39 @@ if (MSVC)
)
endif()
# Install a pkg-config file, so other tools can find this.
# Install a pkg-config file, so other tools can find this. It carries the same
# compile definitions as the target above.
set(NLOHMANN_JSON_PKGCONFIG_CFLAGS "")
if (NOT JSON_GlobalUDLs)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_GLOBAL_UDLS=0")
endif()
if (NOT JSON_ImplicitConversions)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_IMPLICIT_CONVERSIONS=0")
endif()
if (JSON_DisableEnumSerialization)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DISABLE_ENUM_SERIALIZATION=1")
endif()
if (JSON_DisableTupleReferenceConversion)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DISABLE_TUPLE_REFERENCE_CONVERSION=1")
endif()
if (JSON_Diagnostics)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DIAGNOSTICS=1")
endif()
if (JSON_Diagnostic_Positions)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DIAGNOSTIC_POSITIONS=1")
endif()
if (JSON_LegacyDiscardedValueComparison)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1")
endif()
if (JSON_StrictNulHandling)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_STRICT_NUL_HANDLING=1")
endif()
if (JSON_StrictBinaryUTF8)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_STRICT_BINARY_UTF8=1")
endif()
if (JSON_DeleteDeprecatedFunctions)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DELETE_DEPRECATED_FUNCTIONS=1")
endif()
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
+27 -5
View File
@@ -196,19 +196,19 @@ Further documentation:
## REUSE
### `.reuse/dep5`
### `REUSE.toml`
The file defines the licenses of certain third-party components in the repository. The root `Makefile` contains a target `reuse` that checks for compliance.
Further documentation:
- [DEP5](https://reuse.software/spec-3.2/#dep5-deprecated)
- [REUSE.toml](https://reuse.software/spec-3.3/#reusetoml)
- [reuse command-line tool](https://pypi.org/project/reuse/)
- [documentation of linting](https://reuse.readthedocs.io/en/stable/man/reuse-lint.html)
- [REUSE](http://reuse.software)
> [!IMPORTANT]
> The filename `.reuse/dep5` is predetermined by REUSE. Alternatively, a `REUSE.toml` file can be used.
> The filename `REUSE.toml` is predetermined by REUSE. Alternatively, a `.reuse/dep5` file (deprecated) can be used.
### `.reuse/templates`
@@ -249,9 +249,31 @@ make BUILD.bazel
The "Check amalgamation" workflow fails if the file is out of date.
### `meson.build`
### `meson.build` and `meson_options.txt`
The build definition for the [Meson](https://mesonbuild.com) build system.
Meson build definitions suitable for use as a subproject ("wrap" in Meson terminology).
Projects wishing to use the wrap can execute:
```sh
meson wrap install nlohmann_json
```
Which allows Meson to build from source when a system provided dependency isn't available.
To build directly:
```sh
meson setup builddir
ninja -C builddir
```
`meson_options.txt` defines the options, which mirror the CMake options that change the library's target (for example,
`-DDiagnostics=true`). Meson requires this file next to `meson.build`, so it is also part of `include.zip`. `make check_build_options`
([`tools/check_build_options`](tools/check_build_options/README.md)) checks in CI that both files and the pkg-config files
stay in sync with the CMake options.
When installing, `meson.build` installs the headers, a pkg-config file, and the CMake package config files, so that
`find_package(nlohmann_json)` works. As Meson cannot generate `nlohmann_jsonTargets.cmake` itself, it is created from
the template `cmake/nlohmann_jsonTargets.cmake.in`, which is only used by Meson.
### `Package.swift`
+24 -8
View File
@@ -1,4 +1,4 @@
.PHONY: pretty clean ChangeLog.md release update_hedley update_hedley_undef BUILD.bazel natvis macro_builder_check
.PHONY: pretty clean ChangeLog.md release update_hedley update_hedley_undef BUILD.bazel natvis macro_builder_check check_build_options
##########################################################################
# configuration
@@ -7,6 +7,9 @@
# find GNU sed to use `-i` parameter
SED:=$(shell command -v gsed || which sed)
# find GNU tar to use `--sort` and `--pax-option` parameters
TAR:=$(shell command -v gtar || which tar)
##########################################################################
# source files
@@ -23,6 +26,7 @@ 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
@@ -34,7 +38,7 @@ MACRO_SCOPE_HPP=include/nlohmann/detail/macro_scope.hpp
# main target
all:
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd,_literals}.hpp from the include/nlohmann sources"
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd,_literals,_view}.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"
@@ -87,10 +91,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) 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) $(AMALGAMATED_VIEW_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)
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE)
$(MAKE) pretty
# call the amalgamation tool for json.hpp
@@ -105,6 +109,9 @@ $(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
# regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp
natvis:
python3 tools/generate_natvis/generate_natvis.py .
@@ -124,18 +131,25 @@ macro_builder_check:
diff "$$TMPDIR/paste.hpp" "$$TMPDIR/paste_actual.hpp" || (echo "===================================================================\n $(MACRO_SCOPE_HPP) (NLOHMANN_JSON_EXPAND..NLOHMANN_JSON_DOUBLE_PASTE63) is out of date!\n Regenerate it, see tools/macro_builder/README.md.\n===================================================================" ; exit 1); \
diff "$$TMPDIR/type_body.hpp" "$$TMPDIR/type_body_actual.hpp" || (echo "===================================================================\n $(MACRO_SCOPE_HPP) (NLOHMANN_JSON_TYPE_BODY) is out of date!\n Regenerate it, see tools/macro_builder/README.md.\n===================================================================" ; exit 1)
# check that the Meson build and the pkg-config files offer the options of the CMake target
check_build_options:
python3 tools/check_build_options/check_build_options.py .
# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources
check-amalgamation:
@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~
@mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~
@mv $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~
@mv $(AMALGAMATED_VIEW_FILE) $(AMALGAMATED_VIEW_FILE)~
@$(MAKE) amalgamate
@diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false)
@diff $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) ; false)
@diff $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE) ; false)
@diff $(AMALGAMATED_VIEW_FILE) $(AMALGAMATED_VIEW_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_VIEW_FILE)~ $(AMALGAMATED_VIEW_FILE) ; false)
@mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE)
@mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE)
@mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE)
@mv $(AMALGAMATED_VIEW_FILE)~ $(AMALGAMATED_VIEW_FILE)
@mv BUILD.bazel BUILD.bazel~
@$(MAKE) BUILD.bazel
@diff BUILD.bazel BUILD.bazel~ || (echo "===================================================================\n BUILD.bazel is out of date! Please run 'make BUILD.bazel'.\n===================================================================" ; mv BUILD.bazel~ BUILD.bazel ; false)
@@ -174,14 +188,14 @@ ChangeLog.md:
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
json.tar.xz:
mkdir json
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include -type f) json
gtar --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include src/modules -type f) json
$(TAR) --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
rm -fr json
# 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) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT
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
# Create the files for a release and add signatures and hashes.
release: include.zip json.tar.xz
@@ -191,11 +205,13 @@ 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
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
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
cd release_files ; shasum -a 256 $$(find . -type f -not -name '*.asc' | sed 's|^\./||' | sort) > hashes.txt
+1 -1
View File
@@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "nlohmann-json",
platforms: [
.iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v4), .visionOS(.v1)
.iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v9), .visionOS(.v1)
],
products: [
.library(name: "json", targets: ["json"])
+28 -14
View File
@@ -7,7 +7,7 @@
[![Coverage Status](https://coveralls.io/repos/github/nlohmann/json/badge.svg?branch=develop)](https://coveralls.io/github/nlohmann/json?branch=develop)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/e0d1a9d5d6fd46fcb655c4cb930bb3e8)](https://app.codacy.com/gh/nlohmann/json/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/json.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/json.svg)](https://issues.oss-fuzz.com/issues?q=project:json)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/1mp10JbaANo6FUc7)
[![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://json.nlohmann.me)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/develop/LICENSE.MIT)
@@ -361,7 +361,7 @@ std::cout << j_string << " == " << serialized_string << std::endl;
[`.dump()`](https://json.nlohmann.me/api/basic_json/dump/) returns the originally stored string value.
Note the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://json.nlohmann.me/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
Note the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://json.nlohmann.me/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace`, `json::error_handler_t::ignore`, or `json::error_handler_t::keep` are used as error handlers.
#### To/from streams (e.g., files, string streams)
@@ -1187,6 +1187,14 @@ binary.set_subtype(0x10);
auto cbor = 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).
@@ -1202,15 +1210,18 @@ language bindings, format converters, and the like. See the curated [Ecosystem](
Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
- GCC 4.8 - 14.2 (and possibly later)
- Clang 3.4 - 21.0 (and possibly later)
- Apple Clang 9.1 - 16.0 (and possibly later)
- Intel C++ Compiler 17.0.2 (and possibly later)
- Nvidia CUDA Compiler 11.0.221 (and possibly later)
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
- Microsoft Visual C++ 2022 / Build Tools 19.30.30709.0 (and possibly later)
- GCC 4.8 - 16.2 (and possibly later)
- Clang 3.4 - 22.1 (and possibly later)
- Apple Clang 15.0 - 21.0 (and possibly later)
- Intel C++ Compiler Classic (icpc) 2021.10
- Intel oneAPI DPC++/C++ Compiler (icpx) 2025.3 (and possibly later)
- NVIDIA CUDA Compiler (nvcc) 11.8 - 12.6 (and possibly later)
- NVIDIA HPC SDK C++ Compiler (nvc++) 25.5 (and possibly later)
- Microsoft Visual C++ 2015 / MSVC 19.0 (and possibly later)
- Microsoft Visual C++ 2017 / MSVC 19.16 (and possibly later)
- Microsoft Visual C++ 2019 / MSVC 19.29 (and possibly later)
- Microsoft Visual C++ 2022 / MSVC 19.44 (and possibly later)
- Microsoft Visual C++ 2026 / MSVC 19.51 (and possibly later)
I would be happy to learn about other compilers/versions.
@@ -1391,9 +1402,12 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I
- The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2008-2009 [Björn Hoehrmann](https://bjoern.hoehrmann.de/) <bjoern@hoehrmann.de>
- The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2009 [Florian Loitsch](https://florian.loitsch.com/)
- The class contains a port of the shortest double-to-decimal conversion of [Żmij](https://github.com/vitaut/zmij) by Victor Zverovich, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2025 [Victor Zverovich](https://github.com/vitaut)
- The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
- The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
- The class contains an adapted version of the Eisel-Lemire algorithm and its table of powers of five from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright &copy; 2021 The fast_float authors
- The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, 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.
- The view's parser (`<nlohmann/json_view.hpp>`) validates non-ASCII strings with the vector UTF-8 check of [simdjson](https://github.com/simdjson/simdjson) by Daniel Lemire, Geoff Langdale, John Keiser, and contributors (its "lookup4" algorithm and tables, after J. Keiser and D. Lemire, "Validating UTF-8 In Less Than One Instruction Per Byte", 2021), which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here) and the Apache 2.0 License. Copyright &copy; 2018-2025 The simdjson authors
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
@@ -1401,7 +1415,7 @@ The library is compliant to version 3.3 of the [**REUSE specification**](https:/
- Every source file contains an SPDX copyright header.
- The full text of all licenses used in the repository can be found in the `LICENSES` folder.
- File `.reuse/dep5` contains an overview of all files' copyrights and licenses.
- File `REUSE.toml` contains an overview of all files' copyrights and licenses.
- Run `pipx run reuse lint` to verify the project's REUSE compliance and `pipx run reuse spdx` to generate a SPDX SBOM.
## Contact
@@ -1914,7 +1928,7 @@ The library supports **Unicode input** as follows:
- [Unicode noncharacters](https://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library.
- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors.
- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
- When you store strings with different encodings in the library, calling [`dump()`](https://json.nlohmann.me/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
- When you store strings with different encodings in the library, calling [`dump()`](https://json.nlohmann.me/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace`, `json::error_handler_t::ignore`, or `json::error_handler_t::keep` are used as error handlers.
- To store wide strings (e.g., `std::wstring`), you need to convert them to a UTF-8 encoded `std::string` before, see [an example](https://json.nlohmann.me/home/faq/#wide-string-handling).
### Comments in JSON
+52
View File
@@ -0,0 +1,52 @@
version = 1
SPDX-PackageName = "json"
SPDX-PackageSupplier = "Niels Lohmann <mail@nlohmann.me>"
SPDX-PackageDownloadLocation = "https://github.com/nlohmann/json"
[[annotations]]
path = "**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me>"
SPDX-License-Identifier = "MIT"
[[annotations]]
path = "include/nlohmann/thirdparty/hedley.hpp"
precedence = "aggregate"
SPDX-FileCopyrightText = "2016-2021 Evan Nemerson <evan@nemerson.com>"
SPDX-License-Identifier = "CC0"
[[annotations]]
path = "include/nlohmann/detail/meta/cpp_future.hpp"
precedence = "aggregate"
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors"
SPDX-License-Identifier = "MIT AND Apache-2.0"
[[annotations]]
path = "tests/thirdparty/doctest/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2016-2023 Viktor Kirilov"
SPDX-License-Identifier = "MIT"
[[annotations]]
path = "tests/thirdparty/fifo_map/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2015-2017 Niels Lohmann"
SPDX-License-Identifier = "MIT"
[[annotations]]
path = "tests/thirdparty/imapdl/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2017 Georg Sauthoff <mail@gms.tf>"
SPDX-License-Identifier = "GPL-3.0-only"
[[annotations]]
path = "tools/amalgamate/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2012 Erik Edlund <erik.edlund@32767.se>"
SPDX-License-Identifier = "BSD-3-Clause"
[[annotations]]
path = "tools/gdb_pretty_printer/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2020 Hannes Domani <https://github.com/ssbssa>"
SPDX-License-Identifier = "MIT"
+28 -10
View File
@@ -249,6 +249,20 @@ add_custom_target(ci_test_strict_nul_handling
COMMENT "Compile and test with strict NUL-byte handling enabled"
)
###############################################################################
# Delete the deprecated functions.
###############################################################################
add_custom_target(ci_test_delete_deprecated_functions
COMMAND ${CMAKE_COMMAND}
-DCMAKE_BUILD_TYPE=Debug -GNinja
-DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_DeleteDeprecatedFunctions=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_delete_deprecated_functions
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_delete_deprecated_functions
COMMAND cd ${PROJECT_BINARY_DIR}/build_delete_deprecated_functions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
COMMENT "Compile and test with the deprecated functions deleted"
)
###############################################################################
# Disable global UDLs.
###############################################################################
@@ -362,7 +376,7 @@ add_custom_target(ci_test_coverage
# Sanitizers.
###############################################################################
set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base")
set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base -fsanitize-ignorelist=${PROJECT_SOURCE_DIR}/cmake/clang_sanitizer_ignorelist.txt")
add_custom_target(ci_test_clang_sanitizer
COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND}
@@ -396,10 +410,11 @@ 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~
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~ ${include_dir}/json_view.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
@@ -409,12 +424,14 @@ 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 venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.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_view.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}
@@ -442,13 +459,14 @@ add_custom_target(ci_test_single_header
# Valgrind.
###############################################################################
# The Unicode test (~17M assertions) is too slow under Valgrind.
add_custom_target(ci_test_valgrind
COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND}
-DCMAKE_BUILD_TYPE=Debug -GNinja
-DJSON_BuildTests=ON -DJSON_Valgrind=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_valgrind
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_valgrind
COMMAND cd ${PROJECT_BINARY_DIR}/build_valgrind && ${CMAKE_CTEST_COMMAND} -L valgrind --parallel ${N} --output-on-failure
COMMAND cd ${PROJECT_BINARY_DIR}/build_valgrind && ${CMAKE_CTEST_COMMAND} -L valgrind --exclude-regex "test-unicode" --parallel ${N} --output-on-failure
COMMENT "Compile and test with Valgrind"
)
@@ -705,7 +723,7 @@ ci_get_cmake(4.0.0 CMAKE_4_0_0_BINARY)
# the tests require CMake 3.13 or later, so they are excluded for CMake 3.5.0
set(JSON_CMAKE_FLAGS_3_5_0 JSON_Diagnostics JSON_Diagnostic_Positions JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization
JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind
JSON_StrictNulHandling JSON_StrictBinaryUTF8)
JSON_StrictNulHandling JSON_StrictBinaryUTF8 JSON_DeleteDeprecatedFunctions)
set(JSON_CMAKE_FLAGS_3_31_6 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
set(JSON_CMAKE_FLAGS_4_0_0 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
@@ -773,7 +791,7 @@ foreach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6 g++-7 g++-8 g++-9 g++-10 g++-11 cla
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
${ADDITIONAL_FLAGS}
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
COMMENT "Compile and test with ${COMPILER}"
)
endif()
@@ -787,7 +805,7 @@ add_custom_target(ci_test_compiler_default
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_default
${ADDITIONAL_FLAGS}
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_default --parallel ${N}
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_default && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" -LE git_required --output-on-failure
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_default && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE git_required --output-on-failure
COMMENT "Compile and test with default C++ compiler"
)
@@ -825,7 +843,7 @@ add_custom_target(ci_icpc
-DJSON_BuildTests=ON -DJSON_FastTests=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpc
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpc
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
COMMENT "Compile and test with ICPC"
)
@@ -836,7 +854,7 @@ add_custom_target(ci_icpx
-DJSON_BuildTests=ON -DJSON_FastTests=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpx
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpx
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpx && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure
COMMAND cd ${PROJECT_BINARY_DIR}/build_icpx && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure
COMMENT "Compile and test with ICPX (Intel oneAPI DPC++/C++)"
)
@@ -872,7 +890,7 @@ add_custom_target(ci_nvhpc
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_nvhpc
# the pipes are escaped so the surrounding shell passes them to ctest verbatim
# instead of treating them as shell pipe operators
COMMAND cd ${PROJECT_BINARY_DIR}/build_nvhpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode\\|test-comparison_cpp20\\|test-comparison_legacy_cpp20\\|test-constructor1_cpp11\\|test-deserialization_cpp20" --output-on-failure
COMMAND cd ${PROJECT_BINARY_DIR}/build_nvhpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-comparison_cpp20\\|test-comparison_legacy_cpp20\\|test-constructor1_cpp11\\|test-deserialization_cpp20" --output-on-failure
COMMENT "Compile and test with NVIDIA HPC SDK (nvc++)"
)
+14
View File
@@ -0,0 +1,14 @@
# Sanitizer ignore list for ci_test_clang_sanitizer (-fsanitize-ignorelist).
#
# libstdc++ 14's <format> declares `_Scanner(basic_string_view<_CharT>, size_t __nargs = -1)`, so every std::format
# call converts -1 to size_t, which -fsanitize=integer reports as implicit-integer-sign-change. This is
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119429, not a bug in this library. Only that check and only <format> are
# excluded, so implicit sign changes in the library and the tests are still reported.
#
# 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
+42
View File
@@ -0,0 +1,42 @@
# Imported target for installations made with Meson (see meson.build).
#
# CMake installations generate this file with install(EXPORT ...). Meson cannot
# do that, but as the library is header-only, the target only needs an include
# directory, the C++ standard, and the compile definitions of the options that
# differ from their defaults. Paths are computed relative to this file so that
# the installation can be relocated (e.g., into a sysroot), unless includedir or
# datadir is outside the prefix.
if(TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@)
return()
endif()
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_CONFIG_TO_PREFIX@" ABSOLUTE)
# As in CMake's generated file: avoid "//include" for an installation to "/".
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
add_library(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED)
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "@NLOHMANN_JSON_INCLUDE_DIR@"
)
if(CMAKE_VERSION VERSION_LESS 3.8)
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_COMPILE_FEATURES cxx_range_for
)
else()
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_COMPILE_FEATURES cxx_std_11
)
endif()
set(_NLOHMANN_JSON_COMPILE_DEFINITIONS "@NLOHMANN_JSON_COMPILE_DEFINITIONS@")
if(_NLOHMANN_JSON_COMPILE_DEFINITIONS)
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "${_NLOHMANN_JSON_COMPILE_DEFINITIONS}"
)
endif()
unset(_NLOHMANN_JSON_COMPILE_DEFINITIONS)
unset(_IMPORT_PREFIX)
+1 -1
View File
@@ -4,4 +4,4 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: JSON for Modern C++
Version: @PROJECT_VERSION@
Cflags: -I${includedir}
Cflags: -I${includedir}@NLOHMANN_JSON_PKGCONFIG_CFLAGS@
+2
View File
@@ -48,6 +48,8 @@ cc_library(
name = "singleheader-json",
hdrs = [
"single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp",
"single_include/nlohmann/json_view.hpp",
],
includes = ["single_include"],
visibility = ["//visibility:public"],
+1 -1
View File
@@ -64,7 +64,7 @@ if(MODE STREQUAL "undef")
# recipe is self-contained and its output is byte-stable across reruns.
# The embedded SPDX tags below are part of the *generated* file's
# content, not a REUSE header for this .cmake script itself (which is
# already covered by the blanket "Files: *" rule in .reuse/dep5) -- keep
# already covered by the blanket path = "**" rule in REUSE.toml) -- keep
# them wrapped in REUSE-IgnoreStart/End so `reuse lint` does not try to
# parse "MIT\n")" as this file's own SPDX-License-Identifier value.
# REUSE-IgnoreStart
+75
View File
@@ -131,8 +131,74 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_string', 'Meth
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_ubjson', 'Function', 'api/basic_json/to_ubjson/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value', 'Method', 'api/basic_json/value/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value_t', 'Enum', 'api/basic_json/value_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::with_t', 'Type', 'api/basic_json/with_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::~basic_json', 'Method', 'api/basic_json/~basic_json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document', 'Class', 'api/basic_json_document/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::basic_json_document', 'Constructor', 'api/basic_json_document/basic_json_document/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::accept', 'Function', 'api/basic_json_document/accept/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::erase', 'Method', 'api/basic_json_document/erase/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::insert', 'Method', 'api/basic_json_document/insert/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::is_discarded', 'Method', 'api/basic_json_document/is_discarded/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::memory_usage', 'Method', 'api/basic_json_document/memory_usage/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::node_count', 'Method', 'api/basic_json_document/node_count/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::owns_source', 'Method', 'api/basic_json_document/owns_source/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse', 'Function', 'api/basic_json_document/parse/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse_copy', 'Function', 'api/basic_json_document/parse_copy/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::push_back', 'Method', 'api/basic_json_document/push_back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::read', 'Method', 'api/basic_json_document/read/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::root', 'Method', 'api/basic_json_document/root/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::set', 'Method', 'api/basic_json_document/set/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::shrink_to_fit', 'Method', 'api/basic_json_document/shrink_to_fit/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::source', 'Method', 'api/basic_json_document/source/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view', 'Class', 'api/basic_json_view/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::basic_json_view', 'Constructor', 'api/basic_json_view/basic_json_view/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::at', 'Method', 'api/basic_json_view/at/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::back', 'Method', 'api/basic_json_view/back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::begin', 'Method', 'api/basic_json_view/begin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::cbegin', 'Method', 'api/basic_json_view/cbegin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::cend', 'Method', 'api/basic_json_view/cend/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::contains', 'Method', 'api/basic_json_view/contains/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::count', 'Method', 'api/basic_json_view/count/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::dump', 'Method', 'api/basic_json_view/dump/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::empty', 'Method', 'api/basic_json_view/empty/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::end', 'Method', 'api/basic_json_view/end/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::find', 'Method', 'api/basic_json_view/find/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::front', 'Method', 'api/basic_json_view/front/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::get', 'Method', 'api/basic_json_view/get/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::get_string', 'Method', 'api/basic_json_view/get_string/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::get_to', 'Method', 'api/basic_json_view/get_to/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_array', 'Method', 'api/basic_json_view/is_array/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_binary', 'Method', 'api/basic_json_view/is_binary/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_boolean', 'Method', 'api/basic_json_view/is_boolean/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_discarded', 'Method', 'api/basic_json_view/is_discarded/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_null', 'Method', 'api/basic_json_view/is_null/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number', 'Method', 'api/basic_json_view/is_number/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number_float', 'Method', 'api/basic_json_view/is_number_float/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number_integer', 'Method', 'api/basic_json_view/is_number_integer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number_unsigned', 'Method', 'api/basic_json_view/is_number_unsigned/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_object', 'Method', 'api/basic_json_view/is_object/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_primitive', 'Method', 'api/basic_json_view/is_primitive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_string', 'Method', 'api/basic_json_view/is_string/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_structured', 'Method', 'api/basic_json_view/is_structured/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::items', 'Method', 'api/basic_json_view/items/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::materialize', 'Method', 'api/basic_json_view/materialize/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::number_format', 'Enum', 'api/basic_json_view/number_format/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::number_token', 'Method', 'api/basic_json_view/number_token/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator bool', 'Method', 'api/basic_json_view/operator_bool/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator<<', 'Operator', 'api/basic_json_view/operator_ltlt/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator[]', 'Operator', 'api/basic_json_view/operator[]/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator==', 'Operator', 'api/basic_json_view/operator_eq/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator!=', 'Operator', 'api/basic_json_view/operator_ne/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::size', 'Method', 'api/basic_json_view/size/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::source_offset', 'Method', 'api/basic_json_view/source_offset/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type', 'Method', 'api/basic_json_view/type/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type_name', 'Method', 'api/basic_json_view/type_name/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::value', 'Method', 'api/basic_json_view/value/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_document', 'Class', 'api/json_document/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_editable_document', 'Class', 'api/json_editable_document/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_editable_view', 'Class', 'api/json_editable_view/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_view', 'Class', 'api/json_view/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer', 'Class', 'api/json_pointer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::back', 'Method', 'api/json_pointer/back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::empty', 'Method', 'api/json_pointer/empty/index.html');
@@ -170,6 +236,10 @@ INSERT INTO searchIndex(name, type, path) VALUES ('operator""_json_pointer', 'Li
INSERT INTO searchIndex(name, type, path) VALUES ('operator<<', 'Operator', 'api/operator_ltlt/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('operator>>', 'Operator', 'api/operator_gtgt/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json', 'Class', 'api/ordered_json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_document', 'Class', 'api/ordered_json_document/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_editable_document', 'Class', 'api/ordered_json_editable_document/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_editable_view', 'Class', 'api/ordered_json_editable_view/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_view', 'Class', 'api/ordered_json_view/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('ordered_map', 'Class', 'api/ordered_map/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('std::formatter<basic_json>', 'Class', 'api/basic_json/std_formatter/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('std::hash<basic_json>', 'Class', 'api/basic_json/std_hash/index.html');
@@ -200,6 +270,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('Iterators', 'Guide', 'feature
INSERT INTO searchIndex(name, type, path) VALUES ('JSON Merge Patch', 'Guide', 'features/merge_patch/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON Patch and Diff', 'Guide', 'features/json_patch/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON Pointer', 'Guide', 'features/json_pointer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Zero-copy JSON views', 'Guide', 'features/json_view/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('nlohmann Namespace', 'Guide', 'features/namespace/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Types', 'Guide', 'features/types/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Types: Number Handling', 'Guide', 'features/types/number_handling/index.html');
@@ -219,6 +290,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('Supported Macros', 'Guide', '
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'api/macros/json_assert/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_BRACE_INIT_COPY_SEMANTICS', 'Macro', 'api/macros/json_brace_init_copy_semantics/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'api/macros/json_throw_user/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DELETE_DEPRECATED_FUNCTIONS', 'Macro', 'api/macros/json_delete_deprecated_functions/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'api/macros/json_diagnostics/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTIC_POSITIONS', 'Macro', 'api/macros/json_diagnostic_positions/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'api/macros/json_disable_enum_serialization/index.html');
@@ -249,6 +321,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('JSON_TRY_USER', 'Macro', 'api
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_GLOBAL_UDLS', 'Macro', 'api/macros/json_use_global_udls/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'api/macros/json_use_implicit_conversions/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON', 'Macro', 'api/macros/json_use_legacy_discarded_value_comparison/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS', 'Macro', 'api/macros/json_use_objects_for_enum_keyed_maps/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_USE_SIMDUTF', 'Macro', 'api/macros/json_use_simdutf/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Macros', 'Macro', 'api/macros/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
@@ -284,3 +357,5 @@ INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM_
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MAJOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_MINOR', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_VERSION_PATCH', 'Macro', 'api/macros/nlohmann_json_version_major/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_VIEW_NO_SIMD', 'Macro', 'api/macros/json_view_no_simd/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_VIEW_USE_SSSE3', 'Macro', 'api/macros/json_view_use_ssse3/index.html');
+1
View File
@@ -233,6 +233,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
- documentation on [checked access](../../features/element_access/checked_access.md)
- [`operator[]`](operator%5B%5D.md) for unchecked access by reference
- [`value`](value.md) for access with default value
- [basic_json_view::at](../basic_json_view/at.md) - the same access on a zero-copy view
## Version history
+1
View File
@@ -58,6 +58,7 @@ Constant.
## See also
- [front](front.md) to access the first element
- [basic_json_view::back](../basic_json_view/back.md) - the same access on a zero-copy view
## Version history
+2
View File
@@ -44,6 +44,8 @@ Constant.
- [rbegin](rbegin.md) returns a reverse iterator to the last element
- [items](items.md) returns an iteration proxy to access keys and values during range-based for loops
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::begin](../basic_json_view/begin.md) - the same iteration on a zero-copy view (in document order,
not sorted by key)
## Version history
@@ -42,6 +42,7 @@ Constant.
- [cend](cend.md) returns a const iterator to one past the last element
- [crbegin](crbegin.md) returns a const reverse iterator to the last element
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::cbegin](../basic_json_view/cbegin.md) - the same iteration on a zero-copy view
## Version history
@@ -9,10 +9,10 @@ enum class cbor_tag_handler_t
};
```
This enumeration is used in the [`from_cbor`](from_cbor.md) function to choose how to treat tags:
This enumeration is used in [`from_cbor`](from_cbor.md) and [`sax_parse`](sax_parse.md) to choose how to treat tags:
error
: throw a `parse_error` exception in case of a tag
: report a parse error in case of a tag (the `from_cbor` overloads throw a `parse_error` exception by default)
ignore
: ignore tags
+1
View File
@@ -42,6 +42,7 @@ Constant.
- [cbegin](cbegin.md) returns a const iterator to the first element
- [crend](crend.md) returns a const reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::cend](../basic_json_view/cend.md) - the same iteration on a zero-copy view
## Version history
@@ -127,6 +127,7 @@ Logarithmic in the size of the JSON object.
- [find](find.md) find a value in an object
- [count](count.md) returns the number of occurrences of a key
- [basic_json_view::contains](../basic_json_view/contains.md) - the same check on a zero-copy view
## Version history
+1
View File
@@ -80,6 +80,7 @@ Logarithmic in the size of the JSON object.
- [find](find.md) find a value in an object
- [contains](contains.md) checks whether a key exists
- [basic_json_view::count](../basic_json_view/count.md) - the same check on a zero-copy view
## Version history
+2 -2
View File
@@ -8,7 +8,7 @@ static basic_json diff(const basic_json& source,
Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling
[`patch`](patch.md) function.
For two JSON values `source` and `target`, the following code yields always `#!cpp true`:
For two JSON values `source` and `target`, the following code always yields `#!cpp true`:
```cpp
source.patch(diff(source, target)) == target;
```
@@ -27,7 +27,7 @@ a JSON patch to convert the `source` to `target`
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes in the JSON value.
Strong guarantee: `source` and `target` are never modified.
## Complexity
+7
View File
@@ -62,6 +62,9 @@ Linear.
## Notes
Floating-point numbers are written with the fewest digits that read back as the same value (for `#!cpp double`; see
[number handling](../../features/types/number_handling.md#number-serialization)).
Binary values are serialized as an object containing two keys:
- "bytes": an array of bytes as integers
@@ -88,6 +91,8 @@ Binary values are serialized as an object containing two keys:
- [to_string](to_string.md) returns a string representation of a JSON value
- [operator<<](../operator_ltlt.md) serialize to stream
- [`basic_json_view::dump`](../basic_json_view/dump.md) the corresponding function of `basic_json_view`, serializing
directly from a flat index without building a `basic_json` value
- [Serialization](../../features/serialization.md) - the serialization article
## Version history
@@ -97,3 +102,5 @@ Binary values are serialized as an object containing two keys:
- Error handlers added in version 3.4.0.
- Serialization of binary values added in version 3.8.0.
- Error handler `keep` added in version 3.13.0.
- Doubles are written with the shortest digits (Żmij instead of Grisu2) since version 3.13.0; about 0.1% of doubles are
written differently, most of them with fewer digits.
+1
View File
@@ -64,6 +64,7 @@ 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
+1
View File
@@ -43,6 +43,7 @@ Constant.
- [cend](cend.md) returns a const iterator to one past the last element
- [rend](rend.md) returns a reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators
- [basic_json_view::end](../basic_json_view/end.md) - the same iteration on a zero-copy view
## Version history
+1
View File
@@ -84,6 +84,7 @@ Logarithmic in the size of the JSON object.
- [count](count.md) returns the number of occurrences of a key
- [contains](contains.md) checks whether a key exists
- [basic_json_view::find](../basic_json_view/find.md) - the same lookup on a zero-copy view
## Version history
@@ -120,3 +120,12 @@ Linear in the size of the input.
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
- Added `error_handler` parameter in version 3.13.0.
!!! warning "Deprecation"
- Overload (2) replaces calls to `from_bjdata` with a pointer and a length as first two parameters, which has been
deprecated in version 3.13.0. This overload will be removed in version 4.0.0. Please replace all calls like
`#!cpp from_bjdata(ptr, len, ...);` with `#!cpp from_bjdata(ptr, ptr+len, ...);`.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
@@ -106,3 +106,12 @@ Linear in the size of the input.
## Version history
- Added in version 3.13.0.
!!! warning "Deprecation"
- Overload (2) replaces calls to `from_bon8` with a pointer and a length as first two parameters, which has been
deprecated in version 3.13.0. This overload will be removed in version 4.0.0. Please replace all calls like
`#!cpp from_bon8(ptr, len, ...);` with `#!cpp from_bon8(ptr, ptr+len, ...);`.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
+1
View File
@@ -51,6 +51,7 @@ Constant.
## See also
- [back](back.md) to access the last element
- [basic_json_view::front](../basic_json_view/front.md) - the same access on a zero-copy view
## Version history
+2
View File
@@ -183,6 +183,8 @@ overload (3).
- [get_ref](get_ref.md) get a reference to the stored value
- [operator ValueType](operator_ValueType.md) get a value via implicit conversion
- [Converting values](../../features/conversions.md) - the type conversions article
- [basic_json_view::get](../basic_json_view/get.md) - the same conversion on a zero-copy view (many types are
converted without ever building a `basic_json` value)
## Version history
@@ -61,6 +61,8 @@ Constant.
## See also
- [get_ptr()](get_ptr.md) get a pointer value
- [basic_json_view::get_string](../basic_json_view/get_string.md) - the closest counterpart on a zero-copy view: a
string without a copy, but as a view rather than a reference to a value that must already exist
## Version history
@@ -72,6 +72,7 @@ Depends on the `json_serializer<ValueType>::from_json()` implementation.
- [get_ref](get_ref.md) get a reference to the stored value
- [get_ptr](get_ptr.md) get a pointer to the stored value
- [Converting values](../../features/conversions.md) - the type conversions article
- [basic_json_view::get_to](../basic_json_view/get_to.md) - the same conversion on a zero-copy view
## Version history
+3
View File
@@ -109,6 +109,9 @@ The class satisfies the following concept requirements:
- **initializer_list_t** - type for initializer lists of `basic_json` values
- [**input_format_t**](input_format_t.md) - type to choose the format to parse
- [**json_sax_t**](../json_sax/index.md) - type for SAX events
- [**with_object_t, with_array_t, with_string_t, with_boolean_t, with_integers_t, with_float_t, with_allocator_t,
with_json_serializer_t, with_binary_t, with_base_class_t**](with_t.md) - types to create a `basic_json` type with
one (or two) replaced template parameters
### Exceptions
@@ -40,6 +40,7 @@ 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,6 +39,7 @@ 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,6 +38,7 @@ 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,6 +85,11 @@ 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,6 +40,7 @@ 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,6 +49,7 @@ 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,6 +40,7 @@ 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,6 +40,7 @@ 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
@@ -40,6 +40,7 @@ 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,6 +40,7 @@ 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,6 +62,7 @@ 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,6 +39,7 @@ 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,6 +57,7 @@ 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
+2
View File
@@ -99,6 +99,8 @@ When iterating over an array, `key()` will return the index of the element as st
- [begin](begin.md) returns an iterator to the first element
- [end](end.md) returns an iterator to one past the last element
- [basic_json_view::items](../basic_json_view/items.md) - the same range on a zero-copy view (`#!cpp const auto`,
not `#!cpp const auto&`: items are produced on the fly)
## Version history
@@ -23,9 +23,10 @@ type to use.
## Template parameters
`NumberFloatType`
: the type to store floating-point numbers. Parsing and serialization are implemented in terms of
`#!cpp std::strtof`/`#!cpp std::strtod`/`#!cpp std::strtold` and `#!cpp std::snprintf`, so the type must be
`#!cpp float`, `#!cpp double`, or `#!cpp long double`. The
: the type to store floating-point numbers. The parser converts `#!cpp float`, `#!cpp double`, and a
`#!cpp long double` that is IEEE 754 binary64 itself and other `#!cpp long double` formats with
`#!cpp std::from_chars` or `#!cpp std::strtold`, and serialization falls back to `#!cpp std::snprintf`, so the
type must be `#!cpp float`, `#!cpp double`, or `#!cpp long double`. The
[binary formats](../../features/binary_formats/index.md) additionally require `#!cpp float` or `#!cpp double`,
because they have no encoding for `#!cpp long double`. See
[Template Parameter Requirements](../../features/types/template_parameters.md#numberfloattype).
@@ -55,6 +56,10 @@ This implementation does exactly follow this approach, as it uses double precisi
smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally
and be serialized to `null`.
During deserialization (from JSON text or any of the binary formats), a finite number that does not fit into
`number_float_t` is rejected with [`out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406), for
example a double-precision number in a binary format when `number_float_t` is `#!cpp float`.
### Storage
Floating-point number values are stored directly inside a `basic_json` type.
@@ -47,8 +47,9 @@ With the default values for `NumberIntegerType` (`std::int64_t`), the default va
When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and
the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of
range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers
will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md).
range will yield over/underflow when used in a constructor. During deserialization (from JSON text or any of the binary
formats), too large or small integer numbers will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md)
or [`number_float_t`](number_float_t.md).
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
@@ -48,8 +48,9 @@ With the default values for `NumberUnsignedType` (`std::uint64_t`), the default
When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and
the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow
when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored
as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md).
when used in a constructor. During deserialization (from JSON text or any of the binary formats), too large or small
integer numbers will automatically be stored as [`number_integer_t`](number_integer_t.md) or
[`number_float_t`](number_float_t.md).
[RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
> Note that when such software is used, numbers that are integers and are in the range [-2<sup>53</sup>+1, 2<sup>53</sup>-1] are
@@ -275,6 +275,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
- documentation on [runtime assertions](../../features/assertions.md)
- see [`at`](at.md) for access by reference with range checking
- see [`value`](value.md) for access with default value
- [basic_json_view::operator[]](../basic_json_view/operator%5B%5D.md) - the same access on a zero-copy view (always
returns a discarded view instead of assuming undefined behavior)
## Version history
@@ -171,6 +171,8 @@ Linear.
- [operator!=](operator_ne.md) compare for inequality
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20)
- [basic_json_view::operator==](../basic_json_view/operator_eq.md) - the same comparison on a zero-copy view, without
building a `basic_json` value for it
## Version history
@@ -95,6 +95,8 @@ Linear.
- [operator==](operator_eq.md) comparison: equal
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20)
- [basic_json_view::operator!=](../basic_json_view/operator_ne.md) - the same comparison on a zero-copy view, without
building a `basic_json` value for it
## Version history
+10 -3
View File
@@ -8,7 +8,8 @@ static bool sax_parse(InputType&& i,
input_format_t format = input_format_t::json,
const bool strict = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
const bool ignore_trailing_commas = false,
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);
// (2)
template<class IteratorType, class SAX, class SentinelType = IteratorType>
@@ -17,13 +18,14 @@ static bool sax_parse(IteratorType first, SentinelType last,
input_format_t format = input_format_t::json,
const bool strict = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
const bool ignore_trailing_commas = false,
const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);
```
Read from input and generate SAX events
1. Read from a compatible input.
2. Read from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support)
2. Read from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support).
The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted
respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to
@@ -82,6 +84,10 @@ The SAX event lister must follow the interface of [`json_sax`](../json_sax/index
: 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)
`tag_handler` (in)
: how to handle CBOR tags; see [`cbor_tag_handler_t`](cbor_tag_handler_t.md). Ignored for formats other than CBOR
(optional, `cbor_tag_handler_t::error` by default).
`first` (in)
: iterator to the start of a character range
@@ -137,6 +143,7 @@ A UTF-8 byte order mark is silently ignored.
- Added in version 3.2.0.
- Ignoring comments via `ignore_comments` added in version 3.9.0.
- Added `ignore_trailing_commas` in version 3.13.0.
- Added `tag_handler` in version 3.13.0.
- Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0.
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
- `JSON_PRECISE_STREAM_POSITION` added in version 3.13.0 to optionally leave a `#!cpp std::istream` positioned right
+1
View File
@@ -55,6 +55,7 @@ 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
+12 -3
View File
@@ -7,8 +7,14 @@ namespace std {
```
Return a hash value for a JSON object. The hash function tries to rely on `std::hash` where possible. Furthermore, the
type of the JSON value is taken into account to have different hash values for `#!json null`, `#!cpp 0`, `#!cpp 0U`, and
`#!cpp false`, etc.
type of the JSON value is taken into account, so `#!json null`, `#!cpp false`, and numbers may hash differently from
each other. Numbers that compare equal under [`operator==`](operator_eq.md) always hash equally, regardless of
whether they are stored as signed integer, unsigned integer, or floating-point number.
Numbers are hashed by their value converted to `number_float_t`. Converting an integer to `number_float_t` therefore
keeps its hash, but converting a floating-point number to an integer type is lossy and can change it: `#!cpp 0.5`
converts to `#!cpp 0`, which need not have the same hash. Unequal numbers can also share a hash value, for example two
large integers that convert to the same `number_float_t`.
## Examples
@@ -26,7 +32,8 @@ type of the JSON value is taken into account to have different hash values for `
--8<-- "examples/std_hash.output"
```
Note the output is platform-dependent.
The hash values shown are examples only. They depend on the platform, the compiler, and the compiler version, and
they can change between versions of this library. Do not persist them or rely on specific values.
## See also
@@ -36,3 +43,5 @@ type of the JSON value is taken into account to have different hash values for `
- Added in version 1.0.0.
- Extended for arbitrary basic_json types in version 3.10.5.
- Numbers that compare equal hash equally since version 3.13.0; before, `#!cpp 0`, `#!cpp 0U`, and `#!cpp 0.0` had
different hash values.
+5 -1
View File
@@ -68,6 +68,8 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
not valid UTF-8 and `error_handler` is `strict` (the default only if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
discarded; example: `"cannot serialize discarded value to BJData"`
## Complexity
@@ -119,4 +121,6 @@ Linear in the size of the JSON value `j`.
- BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
that is not valid UTF-8 unchanged, as before; `strict` (the default if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
array or object was silently skipped, producing invalid BJData.
@@ -58,6 +58,9 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key is
not valid UTF-8 and `error_handler` is `strict` (the default only if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if a value nested in `j` is discarded
(the top-level value itself is covered by `type_error.317` above, since it must be an object); example:
`"cannot serialize discarded value to BSON"`
## Complexity
@@ -110,6 +113,8 @@ pass before anything is written.
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
- Linear in the size of `j`, and no longer limited by the call stack for deeply nested values, since version 3.13.0.
- `out_of_range.415` is now detected before anything is written, like the other exceptions above, since version 3.13.0.
- Throws `type_error.321` for a discarded value nested in `j` since version 3.13.0; previously, it was silently
skipped, producing a document whose declared size did not match what was actually written.
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
that is not valid UTF-8 unchanged, as before; `strict` (the default if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316` before anything
@@ -49,6 +49,8 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
not valid UTF-8 and `error_handler` is `strict` (the default only if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
discarded; example: `"cannot serialize discarded value to CBOR"`
## Complexity
@@ -86,3 +88,5 @@ Linear in the size of the JSON value `j`.
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
that is not valid UTF-8 unchanged, as before; `strict` (the default if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
array or object was silently skipped, producing invalid CBOR.
@@ -54,6 +54,8 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
`"subtype 70000 is too large for the MessagePack ext type (max 255)"`
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
not valid UTF-8 and `error_handler` is `strict`
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
discarded; example: `"cannot serialize discarded value to MessagePack"`
## Complexity
@@ -108,3 +110,5 @@ Linear in the size of the JSON value `j`.
- Fixed in version 3.13.0 to serialize `number_integer_t`/`number_unsigned_t` pairs of different width correctly;
before, integers could be serialized with the wrong value if `number_integer_t` was narrower than
`number_unsigned_t`.
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
array or object was silently skipped, producing invalid MessagePack.
@@ -61,6 +61,8 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
not valid UTF-8 and `error_handler` is `strict` (the default only if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled)
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
discarded; example: `"cannot serialize discarded value to UBJSON"`
## Complexity
@@ -112,3 +114,5 @@ Linear in the size of the JSON value `j`.
- Added `error_handler` parameter in version 3.13.0. Its default, `keep`, writes the bytes of a string or object key
that is not valid UTF-8 unchanged, as before; `strict` (the default if
[`JSON_STRICT_BINARY_UTF8`](../macros/json_strict_binary_utf8.md) is enabled) throws `type_error.316`.
- Throws `type_error.321` for a discarded value since version 3.13.0; previously, a discarded value nested in an
array or object was silently skipped, producing invalid UBJSON.
+1
View File
@@ -52,6 +52,7 @@ 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
@@ -56,6 +56,7 @@ Constant.
- [type](type.md) returns the type of the JSON value
- [value_t](value_t.md) the enumeration of JSON types
- [basic_json_view::type_name](../basic_json_view/type_name.md) - the same function on a zero-copy view
## Version history
+1
View File
@@ -216,6 +216,7 @@ changes to any JSON value.
- see [`at`](at.md) for access by reference with range checking
- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference
- [basic_json_view::value](../basic_json_view/value.md) - the same access on a zero-copy view
## Version history
+136
View File
@@ -0,0 +1,136 @@
# <small>nlohmann::basic_json::</small>with_t
Member alias templates `with_object_t`, `with_array_t`, `with_string_t`, `with_boolean_t`, `with_integers_t`,
`with_float_t`, `with_allocator_t`, `with_json_serializer_t`, `with_binary_t`, and `with_base_class_t`.
```cpp
template<template<typename, typename, typename...> class ObjectType2>
using with_object_t = basic_json<ObjectType2, ArrayType, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
template<template<typename, typename...> class ArrayType2>
using with_array_t = basic_json<ObjectType, ArrayType2, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
template<class StringType2>
using with_string_t = basic_json<ObjectType, ArrayType, StringType2, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
template<class BooleanType2>
using with_boolean_t = basic_json<ObjectType, ArrayType, StringType, BooleanType2,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
template<class NumberIntegerType2, class NumberUnsignedType2>
using with_integers_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
NumberIntegerType2, NumberUnsignedType2, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
template<class NumberFloatType2>
using with_float_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType2,
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;
template<template<typename> class AllocatorType2>
using with_allocator_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType2, JSONSerializer, BinaryType, CustomBaseClass>;
template<template<typename, typename = void> class JSONSerializer2>
using with_json_serializer_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer2, BinaryType, CustomBaseClass>;
template<class BinaryType2>
using with_binary_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType2, CustomBaseClass>;
template<class CustomBaseClass2>
using with_base_class_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass2>;
```
These member alias templates make it easier to create a `basic_json` type that is identical to the current type except
for one (or, in the case of `with_integers_t`, two) of its [template parameters](index.md#template-parameters).
Spelling out all 11 template parameters of `basic_json` just to change a single one is verbose and error-prone; these
aliases only require the replacement type(s).
with_object_t&lt;ObjectType2&gt;
: replaces `ObjectType`
with_array_t&lt;ArrayType2&gt;
: replaces `ArrayType`
with_string_t&lt;StringType2&gt;
: replaces `StringType`
with_boolean_t&lt;BooleanType2&gt;
: replaces `BooleanType`
with_integers_t&lt;NumberIntegerType2, NumberUnsignedType2&gt;
: replaces both `NumberIntegerType` and `NumberUnsignedType`; the two are combined into a single alias because they
are usually changed together (for instance, when switching to fixed-width integer types)
with_float_t&lt;NumberFloatType2&gt;
: replaces `NumberFloatType`
with_allocator_t&lt;AllocatorType2&gt;
: replaces `AllocatorType`
with_json_serializer_t&lt;JSONSerializer2&gt;
: replaces `JSONSerializer`
with_binary_t&lt;BinaryType2&gt;
: replaces `BinaryType`
with_base_class_t&lt;CustomBaseClass2&gt;
: replaces `CustomBaseClass`; see also [`json_base_class_t`](json_base_class_t.md)
## Notes
All other template parameters are kept unchanged, so the resulting type still uses, for instance, the same
`ObjectType` unless `with_object_t` itself is used.
The aliases are members of every `basic_json` specialization, including [`ordered_json`](../ordered_json.md), and the
type they produce is again a `basic_json` specialization. They can therefore be chained to replace several template
parameters at once:
```cpp
using my_json = nlohmann::json::with_integers_t<int, unsigned int>::with_float_t<float>;
using my_ordered_json = nlohmann::ordered_json::with_string_t<std::wstring>;
```
The result is the same type as spelling out all template parameters, so the order of the chained aliases does not
matter. For instance, `nlohmann::json::with_object_t<nlohmann::ordered_map>` is `nlohmann::ordered_json`.
## Examples
??? example
The following code shows how `with_object_t` can be used to create a JSON type that stores object elements in a
`std::map` and therefore keeps them sorted by key, unlike the default type which preserves insertion order
only when `nlohmann::ordered_json` is used.
```cpp
--8<-- "examples/with_t.cpp"
```
Output:
```json
--8<-- "examples/with_t.output"
```
## See also
- [basic_json](index.md#template-parameters) - the template parameters that can be replaced
- [json_base_class_t](json_base_class_t.md) - the type used for `CustomBaseClass`
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,67 @@
# <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.
## 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.
@@ -0,0 +1,58 @@
# <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.
@@ -0,0 +1,128 @@
# <small>nlohmann::basic_json_document::</small>erase
```cpp
// (1)
std::size_t erase(view_type object, string_view_t key);
// (2)
template<typename I>
void erase(view_type array, I idx);
// (3)
std::size_t erase(const json_pointer& ptr);
```
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `erase`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
1. Removes every member of `object` whose key is `key` (see [Notes](#notes) on duplicate keys) and returns how many
were removed; `#!cpp 0` if `object` has no member with this key.
2. Removes the element at index `idx` of `array`, which must already exist (`#!cpp idx < array.size()`).
3. Removes the value the JSON pointer `ptr` refers to, relative to [`root()`](root.md), and returns how many values
were removed: the *parent* of the target must already exist, and the target itself is removed as in 1. (an object
member; `#!cpp 0` or more) or 2. (an array element; always `#!cpp 1`). `ptr` must not be empty -- [`root()`](root.md)
itself cannot be erased.
## Template parameters
`I`
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
`idx` do not participate in overload resolution).
## Parameters
`object` (in)
: the object to remove a member of
`array` (in)
: the array to remove an element of
`key` (in)
: the key of the member(s) to remove
`idx` (in)
: the index of the element to remove; a negative value throws (see [Exceptions](#exceptions))
`ptr` (in)
: a JSON pointer to the value to remove, relative to `root()`
## Return value
1. the number of removed members (`#!cpp 0` if `object` had none with this `key`)
2. (nothing)
3. the number of removed values (`#!cpp 0` or more for an object member, always `#!cpp 1` for an array element)
## Exceptions
1. Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if `object` is not an object -- the
same message [`BasicJsonType::erase`](../basic_json/erase.md) throws for the same type.
2. Throws `type_error.307` if `array` is not an array. Throws
[`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is negative, or if
`#!cpp idx >= array.size()`.
3. Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) ("JSON pointer has no parent")
if `ptr` is empty. Throws what [`at`](../basic_json_view/at.md) throws (overload 3) for resolving `ptr`'s parent.
For the last reference token itself: if the parent is an array, throws what 2. throws for an index that is out of
range, or, for a token that is not a valid array index,
[`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) (a leading `#!cpp '0'`),
[`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) (not a number),
[`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) (too large for `size_type`), or
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) (an empty token); otherwise (an
object, or a primitive value the pointer's parent resolves to) throws what 1. throws.
Every overload also throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view
does not belong to this document") if `object`/`array` is a [discarded](../basic_json_view/is_discarded.md) view or a
view of a *different* document (overloads 1-2 only; overload 3 always starts from this document's own
[`root()`](root.md)).
## Complexity
1. Linear in the number of members of `object`.
2. Linear in the number of elements of `array` at or after `idx` (they move one slot over).
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
that level or the index into the array (as [`at`](../basic_json_view/at.md)), plus the complexity of 1. or 2. for
the last token.
## Notes
!!! info "Duplicate keys"
Overload 1. removes *every* member with `key`, not just the first -- unlike [`set`](set.md), which assigns the
first occurrence and drops the rest. This is why it returns a count rather than a single view: there may be
more than one member removed, or none.
Like [`set`](set.md) and [`push_back`](push_back.md), `erase` never moves an element's *value*: a view still
referring to a removed member or element keeps showing what it last held (see [Edits](index.md#edits)) -- it just no
longer appears when `array`/`object` is read, dumped, or iterated. Removing an element of `array` (2.) does shift the
*links* to the elements after it, the same way `insert`, `set`, or `push_back` on the same array would; any iterator
already taken over `array`/`object` is invalidated by an erase, since it was walking the old layout.
## Examples
??? example
The example below drops a deprecated field and a decommissioned entry from a configuration document -- using all
three overloads -- and shows what stays intact that would not with a plain `json`/`ordered_json` value: the order
of the fields around the ones removed, and the exact spelling of a number that was never touched.
```cpp
--8<-- "examples/basic_json_document__erase.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__erase.output"
```
## See also
- [insert](insert.md) - insert an element into an array
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
- [push_back](push_back.md) - append to an array
- [root](root.md) - the view of the root value, the starting point of overload 3
- [`BasicJsonType::erase`](../basic_json/erase.md) - the corresponding function of `basic_json`
- [Edits](index.md#edits) - what an edit guarantees, for every overload
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,104 @@
# <small>nlohmann::</small>basic_json_document
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
template<typename BasicJsonType, bool Editable = false>
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.
With `#!cpp Editable == true`, the document also offers [`set`](set.md), [`push_back`](push_back.md),
[`insert`](insert.md), and [`erase`](erase.md) to change values in place, see [Edits](#edits) below. The source text
itself is never written; a read-only document (`#!cpp Editable == false`, the default) does not carry any of the
bookkeeping edits need, and calling any of them on one fails to compile (`#!cpp static_assert`).
## 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`.
`Editable`
: whether the document supports [`set`](set.md), [`push_back`](push_back.md), [`insert`](insert.md), and
[`erase`](erase.md) (optional, `#!cpp false` by default). See [Edits](#edits) below.
## Specializations
- [**json_document**](../json_document.md) - read-only documents of the default specialization [`json`](../json.md)
- [**ordered_json_document**](../ordered_json_document.md) - read-only documents of
[`ordered_json`](../ordered_json.md)
- [**json_editable_document**](../json_editable_document.md) - editable documents of [`json`](../json.md)
- [**ordered_json_editable_document**](../ordered_json_editable_document.md) - editable 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, Editable>`)
- **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
- [**set**](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers
to (`#!cpp Editable` documents only)
- [**push_back**](push_back.md) - append to an array (`#!cpp Editable` documents only)
- [**insert**](insert.md) - insert an element into an array before a given position (`#!cpp Editable` documents only)
- [**erase**](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
(`#!cpp Editable` documents only)
## Edits
An editable document (`#!cpp Editable == true`) can be changed after parsing, with [`set`](set.md),
[`push_back`](push_back.md), [`insert`](insert.md), and [`erase`](erase.md);
[`json_editable_document`](../json_editable_document.md) and
[`ordered_json_editable_document`](../ordered_json_editable_document.md) are the corresponding specializations. A few
points apply to every edit:
- **The source text is never written**, and the parsed index never moves: every value keeps the node it was parsed
into, so [views](../basic_json_view/index.md) taken before an edit stay valid, including
[`root()`](root.md). New values (and the element sequences of an edited array/object) go to storage owned by the
document, allocated on demand.
- **A view keeps referring to the same value.** After [`set`](set.md) replaces the value a view refers to, that view
sees the new value; a view of a value that a later edit replaces or drops keeps showing what it last held. An edit
of an array or object, however, **invalidates the iterators taken over it** (its members may now live in a
different sequence), and a string obtained with [`get_string()`](../basic_json_view/get_string.md) stays valid even
as further edits happen (earlier buffers of edited text are kept alive, not overwritten).
- **Values are accepted three ways:** a [`basic_json_view`](../basic_json_view/index.md) of *any* document
(read-only or editable; it is copied, nothing is shared with the source document), a `BasicJsonType` value, or
anything `BasicJsonType` can be constructed from (numbers, strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
- [`dump()`](../basic_json_view/dump.md) writes an edited document with members in document order, new members at
the end, and, with [`number_format::source`](../basic_json_view/number_format.md), keeps the spelling of every
number that was not itself edited -- see [Editing a document](../../features/json_view.md#editing-a-document) for
why this matters.
- [`read()`](read.md) discards all edits, [`shrink_to_fit()`](shrink_to_fit.md) does not move the node index once
there are edits, and [`memory_usage()`](memory_usage.md) includes the memory edits use.
[`source_offset()`](../basic_json_view/source_offset.md) of a value introduced by an edit is
`#!cpp static_cast<std::size_t>(-1)`, the same value it reports for a decoded string.
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,114 @@
# <small>nlohmann::basic_json_document::</small>insert
```cpp
template<typename I, typename V>
view_type insert(view_type array, I idx, V&& value);
```
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `insert`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
Inserts `value` into `array` as a new element before position `idx`, which must not be past the end
(`#!cpp idx <= array.size()`; `#!cpp idx == array.size()` appends, like [`push_back`](push_back.md)). Unlike
[`push_back`](push_back.md), a [null](../basic_json_view/is_null.md) `array` does *not* first become an empty array:
`array` must already be an array.
`value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any* document -- read-only or
editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the
source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers,
strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
## Template parameters
`I`
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
`idx` do not participate in overload resolution).
`V`
: the type of `value`, deduced; see above for what is accepted.
## Parameters
`array` (in)
: the array to insert into
`idx` (in)
: the position to insert `value` before; a negative value throws (see [Exceptions](#exceptions))
`value` (in)
: the value to insert
## Return value
a view of the new element, now holding `value`
## Exception safety
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed
layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave `array` already
switched to that layout even though `value` itself was not inserted.
## Exceptions
Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if `array` is not an array -- the same
message [`BasicJsonType::insert`](../basic_json/insert.md) throws for the same type; a null `array` throws this too
(see above). Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is negative,
or if `#!cpp idx > array.size()`. Throws
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
document") if `array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a *different* document.
Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
[discarded](../basic_json_view/is_discarded.md) view or a [discarded](../basic_json/is_discarded.md) `BasicJsonType`
value, and [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or contains) a
binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `value` is (or contains) a string that is
not valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
## Complexity
Linear in the number of elements of `array` at or after `idx` (they move one slot over), plus time linear in the
size of `value` to encode it into the document's storage (constant for a scalar, linear in the number of nested
values for an array or object): like [`push_back`](push_back.md), the elements of `array` move to a growable block
of links the first time it is inserted into (or [`set`](set.md)/[`push_back`](push_back.md) on), and that block
grows in amortized constant time; inserting before the end within that block still shifts every later element.
## Notes
Like [`set`](set.md) on a member or an element, `insert` never moves an existing *element's value* -- only where
`array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across an
`insert`, and keeps referring to the same element even though its index shifts. Any iterator already taken over
`array` is invalidated, since it was walking the old layout. See [Edits](index.md#edits) for what stays valid across
an edit in general.
## Examples
??? example
The example below inserts a step into the middle of a deployment plan, without touching the steps that come
after it, and shows that a view taken before the insert keeps referring to the same element even though its
index shifts -- something a plain `json`/`ordered_json` array, or its `std::vector`-based storage, has no
equivalent for.
```cpp
--8<-- "examples/basic_json_document__insert.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__insert.output"
```
## See also
- [push_back](push_back.md) - append to an array
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
- [`BasicJsonType::insert`](../basic_json/insert.md) - the corresponding function of `basic_json`
- [Edits](index.md#edits) - what an edit guarantees, for every overload
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,49 @@
# <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.
@@ -0,0 +1,50 @@
# <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.
@@ -0,0 +1,49 @@
# <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.
@@ -0,0 +1,49 @@
# <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.
@@ -0,0 +1,139 @@
# <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 exactly what [`BasicJsonType::parse()`](../basic_json/parse.md) accepts, 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.
## Template parameters
`InputType`
: A compatible input, for instance:
- a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of characters
- a pointer to a null-terminated string of single byte characters
- 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, or anything else [`BasicJsonType::parse()`](../basic_json/parse.md) accepts
`IteratorType`
: a compatible iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of
`#!cpp std::string::iterator`
## 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 4 GiB 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 |
| rvalue `#!cpp std::string` | **owned**, moved in without a copy |
| rvalue byte container other than `#!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.
## 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.
@@ -0,0 +1,77 @@
# <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.
## 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.
@@ -0,0 +1,102 @@
# <small>nlohmann::basic_json_document::</small>push_back
```cpp
template<typename V>
view_type push_back(view_type array, V&& value);
```
Appends `value` as a new last element of `array`. A [null](../basic_json_view/is_null.md) `array` first becomes an
empty array, the same way [`set`](set.md) turns a null `object` into an empty object.
`value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any* document -- read-only or
editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the
source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers,
strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `push_back`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
## Template parameters
`V`
: the type of `value`, deduced; see above for what is accepted.
## Parameters
`array` (in)
: the array (or null value) to append to
`value` (in)
: the value to append
## Return value
a view of the new last element of `array`, now holding `value`
## Exception safety
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed
layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave a partial effect, such
as a null `array` argument already turned into an empty array even though `value` itself was not appended.
## Exceptions
Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) if `array` is neither an array nor
null -- the same message [`BasicJsonType::push_back`](../basic_json/push_back.md) throws for the same type. Throws
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
document") if `array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a *different* document.
Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
[discarded](../basic_json_view/is_discarded.md) view or a [discarded](../basic_json/is_discarded.md) `BasicJsonType`
value, and [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or contains) a
binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `value` is (or contains) a string that is
not valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
## Complexity
Amortized constant, plus time linear in the size of `value` to encode it into the document's storage (constant for
a scalar, linear in the number of nested values for an array or object): the elements of `array` move to a growable
block of links the first time it is appended to (or [`set`](set.md) on), and that block itself grows -- doubling its
capacity, so the cost of growing it amortizes to constant per element -- only once it runs out of room. See
[Notes](#notes).
## Notes
Like [`set`](set.md) on a member or an element, `push_back` never moves an existing element itself -- only where
`array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across a
`push_back`, but any iterator already taken over `array` is invalidated, since it was walking the old layout. See
[Edits](index.md#edits) for what stays valid across an edit in general.
## Examples
??? example
The example below appends records to an array one at a time, as they might arrive from a stream of events,
without ever building a `BasicJsonType` value for the array or for the records already in it, and shows that a
view taken from an earlier `push_back` still refers to the same element once later ones have run.
```cpp
--8<-- "examples/basic_json_document__push_back.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__push_back.output"
```
## See also
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
- [insert](insert.md) - insert an element into an array before a given position
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
- [root](root.md) - the view of the root value
- [`BasicJsonType::push_back`](../basic_json/push_back.md) - the corresponding function of `basic_json`
- [Edits](index.md#edits) - what an edit guarantees, for every overload
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,81 @@
# <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.
Reusing a document matters most for large inputs: the operating system provides the memory of a fresh node index one
page at a time, and every page costs a page fault the first time it is written. On x86-64 Linux (4 KiB pages), parsing
a 55 MB document into a reused document took about 40 % less time than parsing it into a fresh one. Programs that parse
many documents of similar size should therefore keep one document and call `read()`.
## 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.
@@ -0,0 +1,50 @@
# <small>nlohmann::basic_json_document::</small>root
```cpp
view_type root() const noexcept;
```
Returns a view of the root value of the document.
## 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
`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.
@@ -0,0 +1,194 @@
# <small>nlohmann::basic_json_document::</small>set
```cpp
// (1)
template<typename V>
view_type set(view_type target, V&& value);
// (2)
template<typename V>
view_type set(view_type object, string_view_t key, V&& value);
// (3)
template<typename I, typename V>
view_type set(view_type array, I idx, V&& value);
// (4)
template<typename V>
view_type set(const json_pointer& ptr, V&& value);
```
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `set`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
1. Replaces the value `target` refers to with `value`.
2. Sets the member `key` of the object `object` to `value`: assigns it if `object` already has a member with this
key -- the first one, should the key occur more than once, and the later duplicates are then dropped (see the
[Notes](#notes) below) -- or appends a new member at the end otherwise. A [null](../basic_json_view/is_null.md)
`object` first becomes an empty object.
3. Assigns `value` to the element at index `idx` of the array `array`, which must already exist (`#!cpp idx <
array.size()`).
4. Sets the value the JSON pointer `ptr` refers to, relative to [`root()`](root.md), to `value`. The *parent* of the
target must already exist: an object member is set as in 2. (added if it does not exist yet), an array element is
assigned as in 3., and a last reference token of `#!cpp "-"`, or equal to the size of the array, appends `value`
instead, exactly as [`push_back`](push_back.md) would. An empty `ptr` sets [`root()`](root.md) itself, as in 1.
In every overload, `value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any*
document -- read-only or editable, and it does not have to be `target`'s/`object`'s/`array`'s own document -- which
is copied so that nothing is shared with the source document afterward; a `BasicJsonType` value; or anything
`BasicJsonType` can be constructed from (numbers, strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
## Template parameters
`V`
: the type of `value`, deduced; see above for what is accepted.
`I`
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
`idx` do not participate in overload resolution).
## Parameters
`target` (in)
: the value to replace
`object` (in)
: the object (or null value) whose member to set
`array` (in)
: the array whose element to assign
`key` (in)
: the key of the member to set
`idx` (in)
: the index of the element to assign; a negative value throws (see [Exceptions](#exceptions))
`ptr` (in)
: a JSON pointer to the value to set, relative to `root()`
`value` (in)
: the new value
## Return value
1. a view of `target`, now holding `value`
2. a view of the member `key` of `object`, now holding `value`
3. a view of the element `idx` of `array`, now holding `value`
4. a view of the value `ptr` refers to, now holding `value`
## Exception safety
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
for the encoding that is not reclaimed. A failure of a later allocation -- while an edited array or object switches
from its parsed layout to a growable block, see [Notes](#notes) -- can still leave a partial effect, such as a
[null](../basic_json_view/is_null.md) `object`/`array` argument already turned into an empty object/array even
though `value` itself was not linked in.
## Exceptions
1. Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
[discarded](../basic_json_view/is_discarded.md) view, or a [discarded](../basic_json/is_discarded.md)
`BasicJsonType` value (e.g. `#!cpp BasicJsonType(value_t::discarded)`) -- an object or array `value`, of either
kind, is fine and is encoded as a whole subtree.
2. Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if `object` is neither an object
nor null -- the same message [`operator[]`](../basic_json_view/operator%5B%5D.md) throws for a string argument on
such a value. Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `key` is not
valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
Also throws what 1. throws for `value`.
3. Throws `type_error.305` if `array` is not an array -- the same message `operator[]` throws for a numeric argument
on such a value. Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is
negative, or if `#!cpp idx >= array.size()`. Also throws what 1. throws for `value`.
4. Throws what [`at`](../basic_json_view/at.md) throws (overload 3) for resolving `ptr`'s parent, except that a
missing object member or an array index equal to the array's size at the very last reference token is not an
error there (it becomes a new member or an appended element) instead of
[`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403)/[`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402).
For the last reference token itself: if the parent is an object (or a primitive value, where it throws
`type_error.305`), throws what 2. throws; if the parent is an array, throws what 3. throws for an index that is
out of range, or, for a token that is not a valid array index,
[`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) (a leading `#!cpp '0'`),
[`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) (not a number),
[`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) (too large for `size_type`), or
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) (an empty token). Also throws what 1.
throws for `value`.
Every overload also throws [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or
contains) a binary value -- `BasicJsonType` can hold one, but a `json_document` cannot -- and
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
document") if `target`/`object`/`array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a
*different* document (overloads 1-3 only; overload 4 always starts from this document's own [`root()`](root.md)).
## Complexity
1. Linear in the size of `value` (encoding it into the document's storage): constant for a scalar, linear in the
number of nested values for an array or object. If `target` is itself an array or object that spans more than one
node in its parent's original, unedited layout, and `value` is a scalar, replacing it additionally costs time
linear in the number of elements of that parent, the *first* time -- see [Notes](#notes).
2. Linear in the number of members of `object`, to find an existing member with `key`, plus the complexity of 1. for
`value`.
3. Constant, plus the complexity of 1. for `value`.
4. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
that level or the index into the array (as [`at`](../basic_json_view/at.md)), plus the complexity of 2. or 3. for
the last token.
## Notes
!!! info "Duplicate keys"
If `object` already has more than one member with `key` (2.), the *first* one is assigned `value` and every
later member with the same key is removed -- so that a lookup, an iteration, and
[`materialize()`](../basic_json_view/materialize.md) of `object` afterward all agree on a single value for
`key`, the same way [`operator[]`](../basic_json_view/operator%5B%5D.md) already picks the first occurrence of a
duplicate key for reading. See the [Notes on duplicate keys](../basic_json_view/operator%5B%5D.md#notes) of
`operator[]`.
Setting a member (2.) or an element (3., through 4.) of an array or object whose elements have not been edited
before switches it from its parsed layout to a growable block holding links to its elements; a later
[`push_back`](push_back.md) or `set` on the same container reuses that block, growing it (amortized constant time)
only once it runs out of room. This never moves an element itself -- only where the container's *links* to its
elements live -- so a view of an element stays valid, but any iterator already taken over the container is
invalidated, since it was walking the old layout. See [Edits](index.md#edits) for what stays valid across an edit in
general.
The same switch happens, for the same reason, when overload 1. replaces a multi-node array/object value with a
scalar: the *parent's* element sequence is what has to switch to links, not `target` itself, because the parent
originally stepped over `target`'s whole subtree by its node count, which no longer applies once `target` is a
one-node scalar.
## Examples
??? example "Example: (1)/(2)/(3)/(4) replace a value, set a member, assign an element, set via a JSON pointer"
The example below edits a small configuration document -- replacing a value, adding an object member, assigning
an array element, and reaching a field through a JSON pointer -- and shows what
[`dump()`](../basic_json_view/dump.md) preserves that is lost once the same edits are made on a `BasicJsonType`
value instead: the order object members were written in, and the exact spelling of a number that was never
touched.
```cpp
--8<-- "examples/basic_json_document__set.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__set.output"
```
## See also
- [push_back](push_back.md) - append to an array
- [insert](insert.md) - insert an element into an array
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
- [root](root.md) - the view of the root value, the starting point of overload 4
- [`basic_json_view::dump`](../basic_json_view/dump.md) - serialize the document, keeping an untouched number's
spelling with `#!cpp number_format::source`
- [Edits](index.md#edits) - what an edit guarantees, for every overload
- [Editing a document](../../features/json_view.md#editing-a-document) - why editable documents keep the source
text's order and number spelling
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,58 @@
# <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.
@@ -0,0 +1,48 @@
# <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.
+134
View File
@@ -0,0 +1,134 @@
# <small>nlohmann::basic_json_view::</small>at
```cpp
// (1)
basic_json_view at(string_view_t key) const;
basic_json_view at(const char* key) const;
basic_json_view at(const string_t& key) const;
// (2)
basic_json_view at(size_type idx) const;
basic_json_view at(int idx) const;
// (3)
basic_json_view at(const json_pointer& ptr) const;
```
1. Returns the value of the object member with key `key` -- the first one, should the key occur more than once (see
[Notes on duplicate keys](operator[].md#notes)).
2. Returns the array element at index `idx`.
3. Returns the value a JSON pointer `ptr` refers to, starting at this value.
## Parameters
`key` (in)
: object key of the element to access
`idx` (in)
: index of the element to access
`ptr` (in)
: JSON pointer to the element to access
## Return value
1. the value of the first member with key `key`
2. the element at index `idx`
3. the value `ptr` resolves to, starting at this value
## Exception safety
Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.
## Exceptions
1. The function can throw the following exceptions, both with the same message as the corresponding call to
[`BasicJsonType::at`](../basic_json/at.md):
- Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the value is not an object.
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if no member has key `key`.
2. The function can throw the following exceptions, both with the same message as the corresponding call to
[`BasicJsonType::at`](../basic_json/at.md):
- Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the value is not an array.
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `#!cpp idx >= size()`.
3. The function can throw the following exceptions, all with the same message as the corresponding call to
[`BasicJsonType::at`](../basic_json/at.md):
- Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in `ptr`
begins with `#!cpp '0'`.
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in `ptr` is
not a number.
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index in `ptr`
is out of range.
- Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if a reference token is
`#!cpp "-"` at an array -- `at` never inserts an element, so `#!cpp "-"` is always invalid.
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a reference token names
an object member that does not exist.
- Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if `ptr` cannot be resolved
because a reference token is used on a primitive value.
None of these exceptions carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no
`BasicJsonType` value to point at, so the exception is created without one, even if `BasicJsonType` was built with
`JSON_DIAGNOSTICS` enabled.
## Complexity
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
another, in document order, stopping at the first match. Each comparison first checks the key's length --
already known from the index, without reading the key bytes -- before comparing its content.
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time
on average.
2. Linear in `idx`: elements are skipped one at a time from the first one, since they are not a fixed size in the
index (unlike `BasicJsonType`'s array, which is random-access).
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
that level (as 1.) or the index into the array (as 2.).
## Notes
Unlike [`operator[]`](operator[].md), which returns a [discarded](is_discarded.md) view for a missing key or an
out-of-range index, `at` always throws -- exactly as `BasicJsonType::at` does, and with the same messages, so
existing error handling written against `BasicJsonType::at` keeps working unchanged when switched to a view. This
also holds for overload 3: unlike [`operator[]`](operator[].md) with a JSON pointer, which returns a discarded view
for a missing key or an out-of-range index, `at` throws for those too (`out_of_range.403`/`out_of_range.401`).
## Examples
??? example "Example: (1)/(2) access specified element with bounds checking"
The example below reads required fields out of a service configuration with `at`, and shows that the exceptions
it throws -- for a wrong type and for a missing key -- carry the same messages
[`BasicJsonType::at`](../basic_json/at.md) would produce for the same JSON text.
```cpp
--8<-- "examples/basic_json_view__at.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__at.output"
```
??? example "Example: (3) access specified element via JSON pointer with bounds checking"
The example below shows that `at` with a JSON pointer throws exactly the exceptions, with exactly the messages,
that [`BasicJsonType::at`](../basic_json/at.md) throws for the same pointer and the same document.
```cpp
--8<-- "examples/basic_json_view__at_json_pointer.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__at_json_pointer.output"
```
## See also
- [operator[]](operator[].md) - access specified element (returns a discarded view instead of throwing)
- [front](front.md), [back](back.md) - access the first or last element
- [`BasicJsonType::at`](../basic_json/at.md) - the corresponding function of `basic_json`
- [`json_pointer`](../json_pointer/index.md) - JSON pointer type used by overload 3
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,64 @@
# <small>nlohmann::basic_json_view::</small>back
```cpp
basic_json_view back() const;
```
Returns the last element of an array, the last member value of an object, or the value itself if it is primitive
(as for [`BasicJsonType::back()`](../basic_json/back.md), a primitive value is a range of one element).
## Return value
The last element or member value. For a primitive value (number, string, boolean), the value itself.
## Exception safety
Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.
## Exceptions
Throws [`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) if the view is
[null](is_null.md) or [discarded](is_discarded.md), or if it is an empty array or object.
This exception does not carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no
`BasicJsonType` value to point at, so the exception is created without one, even if `BasicJsonType` was built with
`JSON_DIAGNOSTICS` enabled.
## Complexity
Linear in the size of the array or object: unlike [`front()`](front.md), which only ever looks at the first
element, `back()` has to walk every element to find where they end, since elements are not a fixed size in the
index.
## Notes
Unlike [`BasicJsonType::back()`](../basic_json/back.md), which has undefined behavior for an empty array or object,
`back()` throws `invalid_iterator.214` in that case -- the same way it already does for `#!json null` and for a
discarded view, where `BasicJsonType::back()` also throws.
## Examples
??? example
The example below reads only the final status of a build log with `back()`. Even though `back()` is linear in
the number of events (unlike [`front()`](front.md), which is constant), it still avoids building a
`BasicJsonType` value for the events that are not needed.
```cpp
--8<-- "examples/basic_json_view__back.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__back.output"
```
## See also
- [front](front.md) - access the first element
- [`BasicJsonType::back`](../basic_json/back.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,52 @@
# <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`,
[`is_discarded()`](is_discarded.md) is `#!cpp true`, and `#!cpp explicit operator bool()` is `#!cpp false`.
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 by
navigating into a container with [`operator[]`](operator[].md), [`at`](at.md), [`front`](front.md), [`back`](back.md),
[`find`](find.md), or iteration.
## 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
- [operator bool](operator_bool.md) - return whether the view refers to a value
- [root](../basic_json_document/root.md) - the view of a document's root value
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,61 @@
# <small>nlohmann::basic_json_view::</small>begin
```cpp
iterator begin() const noexcept;
```
Returns an iterator to the first element of an array, or the first member value of an object, in **document order**
-- the order the values appear in the source text, not sorted by key. A primitive value iterates as a range of one
element (itself); `#!json null` and a [discarded](is_discarded.md) view iterate as an empty range.
## Return value
Iterator to the first element.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
For an object, iteration visits **every** member, including all occurrences of a duplicate key -- unlike
[`operator[]`](operator[].md), [`at`](at.md), [`find`](find.md), [`contains`](contains.md), and [`count`](count.md),
which all resolve to the *first* member with a given key. See the
[Notes on duplicate keys](operator[].md#notes) of `operator[]`.
Because objects are iterated in document order rather than sorted by key, the order seen here can differ from what
iterating the [`materialize()`](materialize.md)d `BasicJsonType` value would produce: a `#!cpp basic_json` object
(`std::map`-backed by default) sorts its keys, while a view does not.
## Examples
??? example
The example below iterates a log record's members with `begin()`/[`end()`](end.md) and prints them in the order
they were written. Materializing the record into a `BasicJsonType` object and iterating that would instead print
the members sorted by key.
```cpp
--8<-- "examples/basic_json_view__begin.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__begin.output"
```
## See also
- [end](end.md) - returns an iterator to one past the last element
- [cbegin](cbegin.md) - returns a const iterator to the first element
- [items](items.md) - access iterator member functions in range-based for
- [`BasicJsonType::begin`](../basic_json/begin.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,49 @@
# <small>nlohmann::basic_json_view::</small>cbegin
```cpp
iterator cbegin() const noexcept;
```
Returns an iterator to the first element, in [document order](begin.md). Equivalent to [`begin()`](begin.md): a view
is always read-only, so `#!cpp const_iterator` and `#!cpp iterator` are the same type, and `cbegin()` exists only so
that generic code that expects a `cbegin()`/`cend()` pair works with a view too.
## Return value
Iterator to the first element; identical to what [`begin()`](begin.md) returns.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below sums many measurements with `std::accumulate`, using `cbegin()`/[`cend()`](cend.md) as the
range -- the same way it would for any standard container -- without ever materializing the whole array into a
`BasicJsonType` value.
```cpp
--8<-- "examples/basic_json_view__cbegin.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__cbegin.output"
```
## See also
- [begin](begin.md) - returns an iterator to the first element
- [cend](cend.md) - returns a const iterator to one past the last element
- [`BasicJsonType::cbegin`](../basic_json/cbegin.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,49 @@
# <small>nlohmann::basic_json_view::</small>cend
```cpp
iterator cend() const noexcept;
```
Returns an iterator to one past the last element, in [document order](begin.md). Equivalent to [`end()`](end.md): a
view is always read-only, so `#!cpp const_iterator` and `#!cpp iterator` are the same type, and `cend()` exists only
so that generic code that expects a `cbegin()`/`cend()` pair works with a view too.
## Return value
Iterator one past the last element; identical to what [`end()`](end.md) returns.
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Examples
??? example
The example below checks that every record of a batch is an object with `std::all_of`, using
[`cbegin()`](cbegin.md)/`cend()` as the range -- the same way it would for any standard container -- before
materializing any record of the batch.
```cpp
--8<-- "examples/basic_json_view__cend.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__cend.output"
```
## See also
- [end](end.md) - returns an iterator to one past the last element
- [cbegin](cbegin.md) - returns a const iterator to the first element
- [`BasicJsonType::cend`](../basic_json/cend.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,103 @@
# <small>nlohmann::basic_json_view::</small>contains
```cpp
// (1)
bool contains(string_view_t key) const;
bool contains(const char* key) const;
bool contains(const string_t& key) const;
// (2)
bool contains(const json_pointer& ptr) const;
```
1. Checks whether the value is an object with a member with key `key`.
2. Checks whether a JSON pointer `ptr` can be resolved, starting at this value.
## Parameters
`key` (in)
: key value to check its existence
`ptr` (in)
: JSON pointer to check its existence
## Return value
1. `#!cpp true` if the value is an object and has a member with key `key`, `#!cpp false` otherwise
2. `#!cpp true` if `ptr` can be resolved to a value starting at this view, `#!cpp false` otherwise
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
known from the index, without reading the key bytes -- before comparing its content.
Objects with 128 or more members get a hash index while parsing, so that a lookup in them takes constant time
on average.
2. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
that level or the index into the array -- as for [`operator[]`](operator[].md#complexity) and
[`at`](at.md#complexity) with a JSON pointer.
## Notes
Overload 1 always returns `#!cpp false` when the value is not an object -- including a [discarded](is_discarded.md)
view.
!!! info "Postconditions"
If `#!cpp v.contains(key)` returns `#!cpp true`, then `#!cpp v[key]` is not [discarded](is_discarded.md). If
`#!cpp v.contains(ptr)` returns `#!cpp true`, then `#!cpp v[ptr]` is not discarded and `#!cpp v.at(ptr)` does not
throw.
!!! info "Overload 2 never throws"
Unlike [`BasicJsonType::contains(const json_pointer&)`](../basic_json/contains.md), which can throw for certain
malformed pointers (for instance an empty array-index reference token), overload 2 never throws: a missing key,
an out-of-range or malformed array index, a `#!cpp "-"` index, or a reference token used on a primitive all
simply make it return `#!cpp false`.
## Examples
??? example "Example: (1) check with key"
The example below counts how many of a batch of records carry an optional `retry_of` field, using `contains()`
to check without ever materializing a single record of the batch.
```cpp
--8<-- "examples/basic_json_view__contains.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__contains.output"
```
??? example "Example: (2) check with JSON pointer"
The example below checks an optional, nested field with a JSON pointer, and shows two pointers that
`#!cpp contains()` resolves to `#!cpp false` without throwing.
```cpp
--8<-- "examples/basic_json_view__contains_json_pointer.cpp"
```
Output:
```json
--8<-- "examples/basic_json_view__contains_json_pointer.output"
```
## See also
- [find](find.md) - find a value in an object
- [count](count.md) - returns the number of occurrences of a key
- [at](at.md), [operator[]](operator[].md) - resolve a JSON pointer and throw, or return a discarded view
- [`BasicJsonType::contains`](../basic_json/contains.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
Loaded 100 of 424 files, more files were not shown because too many files have changed in this diff. Show more