Compare commits

..
Author SHA1 Message Date
Niels Lohmann 9345fb84a4 Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:44 +02:00
Niels Lohmann 733c947ff2 Keep the view's edit headers clean for clang-tidy in C++17 mode
clang-tidy 22 checks the headers with -std=gnu++17 as well, where it asks
for a transparent comparator and std::make_unique. The regions map uses its
default comparator, and the allocation of the edit state keeps new (the
library is C++11) with a NOLINT.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:43 +02:00
Niels Lohmann 67756a568f Make json_view.hpp pass include-what-you-use
ci_single_binaries runs IWYU with --error on every header. For json_view.hpp
it suggested adding <array> (std::array is used), and the headers that json.hpp
already provides (abi_config, abi_macros, input_adapters, json_pointer,
cpp_future, string_concat, value_t, json_fwd), plus <version> for
std::nullptr_t, and removing <cstddef> and edit_storage.hpp.

- include <array>
- keep <cstddef> (nullptr_t, size_t; IWYU attributes them to <version> and <cstring>)
- tell IWYU not to suggest the headers that json.hpp provides: the amalgamated
  json_view.hpp only includes json.hpp, so including them here would duplicate
  their definitions
- drop edit_storage.hpp, which edit.hpp includes

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:42 +02:00
Niels Lohmann b74911859d Keep a raw string with a backslash out of a CHECK (MSVC C2017)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:41 +02:00
Niels Lohmann 8b0101052b Fix clang-tidy 22 findings in unit-json_view_edit.cpp and edit.hpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:40 +02:00
Niels Lohmann 1e80e54468 Fix clang-tidy 22 findings in the json_view headers
Silence bugprone-casting-through-void for the SSE loads (a reinterpret_cast
would trip -Wcast-align=strict), use auto for a cast initialiser, add
parentheses to a mixed expression, and name bugprone-std-namespace-modification
in the NOLINTs of the tuple_size/tuple_element specialisations.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
(cherry picked from commit 0effbaa7a2)
2026-10-11 10:28:40 +02:00
Niels Lohmann 6b9328b6ab Fix MSVC C4127 in the lookups of editable json documents
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:39 +02:00
Niels Lohmann ae45c369c8 Assign the first member when set() meets duplicate keys again
Lookups find the first member of a repeated key again, so set(object, key,
value) assigns that member (keeping the key where it is) and drops the
others, as documented before, and a view taken from object[key] shows the
new value. This undoes the code and documentation changes of 5cbb8e6d6.
Lookups in edited objects (navigation of editable documents) stop at the
first match, like those of parsed objects.

The tests that commit added expect the first member from lookups now. In the
seeded differential test, the documents with repeated keys repeat them after
the real members; the reference holds the first members, which the edits
address and the lookups are compared with, while materialize() is compared
with what parse() makes of the document's dump.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:38 +02:00
Niels Lohmann 407d2607f0 Assign the member that lookups find when set() meets duplicate keys
An editable document reads the last member of a repeated key (as the
read-only document does), but set(object, key, value) assigned the first
one: a view taken from object[key] before the call did not show the new
value. It now assigns the last member's value, keeps the key at the
position of its first occurrence (where materialize() puts it), and drops
the other members.

The seeded differential test now also edits documents whose objects
repeat keys and compares every lookup (operator[], at, find, value,
contains, count, and JSON pointers) with the parsed basic_json value.
A targeted test covers duplicates before and after edits that move the
object, in large objects with an index, in moved arrays, and in values
copied from other documents.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:37 +02:00
Niels Lohmann e3e208906e Update the json_view banner and type_error.319 for editable documents
The banner still described a read-only view, and the documentation of
type_error.319 listed set and push_back only, although insert rejects
binary values as well.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:36 +02:00
Niels Lohmann 045f2facdc Replace a container by a scalar in constant time once it is linked
Replacing an array or object that spans several nodes by a scalar looks
up its parent from the root (find_parent), which is linear in the size
of the document: setting every element of a 20,000 element array took
more than half a second. The parent only has to switch to links once;
afterward the extent of the replaced value no longer matters. Nodes that
an entry of a moved sequence links to are now marked (node_flags::linked),
and assign() skips the lookup for them.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:36 +02:00
Niels Lohmann 5d5f03d858 Set a null value below a pointer as basic_json does
set(json_pointer, value) turned a null parent into an object for every
last reference token, so "/a/0" and "/a/-" below {"a":null} made
{"a":{"0":1}}, where basic_json's operator[](json_pointer) makes an
array. A null parent now becomes an array for "-" and for digit tokens
(filled with nulls up to the index) and an object otherwise. An invalid
index is reported before the parent changes.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:35 +02:00
Niels Lohmann b24991b546 Allow the edit arena to grow up to 4 GiB - 1 bytes
append_text() doubled the capacity of the arena and rejected the result
if it exceeded 4 GiB, so that an arena of more than 2 GiB could not grow
even though the 32-bit offsets of nodes address 4 GiB - 1 bytes. The
capacity is now clamped to that limit (text_capacity()), and an append
is rejected only if the bytes themselves do not fit.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:34 +02:00
Niels Lohmann 44683394f5 Check strings copied from another document for valid UTF-8
An editable document only holds valid UTF-8, but copy_scalar() copied the
strings and keys of a view of another document unchecked. A document of
a weaker check (or a borrowed text that changed after parsing) could
therefore bring ill-formed UTF-8 into it. The copy is checked now, with
the error that dump() reports for the string; copies within the same
document stay unchecked.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:33 +02:00
Niels Lohmann 5eef3714f6 Do not leave a half-assigned container when set_moved() throws
assign() rewrote the kind, length and extent of a slot before set_moved()
registered its new element sequence. set_moved() can throw
(std::bad_alloc from reserving the bookkeeping vectors) for a slot that
is not moved yet, which left a container without the moved flag that
showed its old children. The bookkeeping is now reserved first
(reserve_moved()), so that nothing after the first write to the slot can
throw. block_of() reserves before it marks anything for the same reason.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:32 +02:00
Niels Lohmann 1d644340d4 Copy nested values into a document without recursion
Counting and copying the nodes of a view or a basic_json value into an
editable document recursed once per nesting level, so that a deeply
nested value overflowed the stack. The four functions now walk the value
with an explicit stack, as materialize() does.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:31 +02:00
Niels Lohmann 4d9e032d7d 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-11 10:28:31 +02:00
Niels Lohmann 671b589d71 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-11 10:28:30 +02:00
Niels Lohmann 3f81f42767 Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:29 +02:00
Niels Lohmann 3c2a32ae74 Move the dump, comparison, and large-object tests to unit-json_view_dump.cpp
The dump and comparison tests moved to their own file in the dump pull
request; the hash index tests of this branch join them there.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:28 +02:00
Niels Lohmann e95e7346a3 Make json_view.hpp pass include-what-you-use
ci_single_binaries runs IWYU with --error on every header. For json_view.hpp
it suggested adding <array> (std::array is used), the headers that json.hpp
already provides (abi_config, abi_macros, input_adapters, json_pointer,
cpp_future, string_concat, value_t, json_fwd), and <version> for
std::nullptr_t, and removing <cstddef>.

- include <array>
- keep <cstddef> (nullptr_t, size_t; IWYU attributes them to <version> and <cstring>)
- tell IWYU not to suggest the headers that json.hpp provides: the amalgamated
  json_view.hpp only includes json.hpp, so including them here would duplicate
  their definitions

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:27 +02:00
Niels Lohmann 9ed32daab8 Index strings with size_t in the colliding-keys test (MSVC C4244 on Win32)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:27 +02:00
Niels Lohmann d3137f4161 Avoid GCC useless-cast and strict-overflow warnings in unit-json_view.cpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:26 +02:00
Niels Lohmann 9a5c0ef4a7 Fix clang-tidy 22 findings in unit-json_view.cpp and unit-json_view_builder.cpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:25 +02:00
Niels Lohmann b11dde3252 Fix clang-tidy 22 findings in the json_view headers
Silence bugprone-casting-through-void for the SSE loads (a reinterpret_cast
would trip -Wcast-align=strict), use auto for a cast initialiser, add
parentheses to a mixed expression, and name bugprone-std-namespace-modification
in the NOLINTs of the tuple_size/tuple_element specialisations.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:24 +02:00
Niels Lohmann a60bff1d7a Keep the first of duplicate keys in the object hash index again
Lookups in objects with 128 members or more return the first member of a
repeated key again, like the linear search of smaller objects. This undoes
the code change of a69542046; its test now expects the first member from
lookups (with and without a table) and the last value from materialize()
and basic_json::parse().

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:23 +02:00
Niels Lohmann 594d65f6f1 Keep the last of duplicate keys in the object hash index
Lookups in objects with 128 members or more now return the last member of
a repeated key, like the linear search of smaller objects and like
materialize() and basic_json::parse(). build_object_index let the first
occurrence win, so the same text gave different results depending on the
size of the object.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:22 +02:00
Niels Lohmann 60a1634772 Document the hash index number in node::extra
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:22 +02:00
Niels Lohmann 88396b715a Use the portable string scan on non-x86 targets that define __SSE2__
WebAssembly with -msse2 defines __SSE2__, but has no <cpuid.h> or x86 intrinsics headers.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:21 +02:00
Niels Lohmann 1f0efd425a Release the spare capacity of the hash index in shrink_to_fit
shrink_to_fit() now trims the tables of large objects like the node array and the decoded strings, and the list of large objects is released as soon as the tables are built.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:20 +02:00
Niels Lohmann 745d0eb328 Bound the probe length of the large-object hash index
The key hash is not seeded, so keys chosen to collide made building the table quadratic (20,000 colliding keys took 470 ms to parse). A key may now sit at most 64 slots from its home slot; if a key would sit further away, the table is dropped and the object is searched linearly. Lookups stop after the same distance.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:19 +02:00
Niels Lohmann 8d33a29ba5 Remove an accidentally committed GCC module cache
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:18 +02:00
Niels Lohmann 62ee0e852a 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-11 10:28:17 +02:00
Niels Lohmann e277ffb647 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-11 10:28:17 +02:00
Niels Lohmann 8506c6b642 Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:16 +02:00
Niels Lohmann d92cb38f2b Make json_view.hpp pass include-what-you-use
ci_single_binaries runs IWYU with --error on every header. For json_view.hpp
it suggested adding <array> (std::array is used), the headers that json.hpp
already provides (abi_config, abi_macros, input_adapters, json_pointer,
cpp_future, string_concat, value_t, json_fwd), and <version> for
std::nullptr_t, and removing <cstddef>.

- include <array>
- keep <cstddef> (nullptr_t, size_t; IWYU attributes them to <version> and <cstring>)
- tell IWYU not to suggest the headers that json.hpp provides: the amalgamated
  json_view.hpp only includes json.hpp, so including them here would duplicate
  their definitions

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:15 +02:00
Niels Lohmann b3086f7e49 Split the dump and comparison tests off unit-json_view.cpp
The MinGW linker of the Windows clang jobs cannot link object files with more
than 32767 sections ("relocation truncated to fit: IMAGE_REL_AMD64_REL32
against `.rdata'"). unit-json_view.cpp reaches that limit as the stack
grows, so its "json_view dump" and "json_view comparison" test cases move
into unit-json_view_dump.cpp. The test generator and has_duplicate_keys()
that both files use move into json_view_test_helpers.hpp.

The new file mentions JSON_HAS_CPP_17, so it is built for C++17 like the file
it was split from.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:14 +02:00
Niels Lohmann 0e2d8975a4 Fix the clang-tidy 22 findings in json_view and its tests
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:13 +02:00
Niels Lohmann 9d43acd174 Document and test first-wins lookups next to dump() and ==
dump() writes every member and == resolves duplicate keys as parse()
does, whereas lookups find the first member of a duplicate key.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:13 +02:00
Niels Lohmann 1d77928d28 Do not shrink the output of dump()
finish() copied the whole output when the buffer was more than twice as
large as the result (citm dump +11%). The tighter source_extent()
estimate already keeps the buffer of a small value small.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:12 +02:00
Niels Lohmann 8fe8c2c8d5 Hold the documents of the dump and comparison tests in names
root() of a temporary document is deleted: its views would dangle.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:11 +02:00
Niels Lohmann 90626e7899 Size the dump buffer of a small value by its own extent
The source extent of a value was read from the next node, falling back to the rest of the document when that node held a decoded string. dump() of a small value could thus allocate a buffer as large as the document. Skip a few such nodes, cap the fallback estimate, and shrink a buffer that is much larger than its output.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:10 +02:00
Niels Lohmann cbdb1fe520 Avoid raw string with escapes inside CHECK macro (MSVC C2017)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:09 +02:00
Niels Lohmann 135f0f37bd 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-11 10:28:08 +02:00
Niels Lohmann 60a0644ba1 Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:08 +02:00
Niels Lohmann 794fdc2b2e Fix the clang-tidy 22 findings in json_view and its tests
The same changes as on the dump branch, where they were first made, so
that this branch passes clang-tidy on its own.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:07 +02:00
Niels Lohmann 60dc5f6ff4 Make json_view.hpp pass include-what-you-use
ci_single_binaries runs IWYU with --error on every header. For json_view.hpp
it suggested adding <array> (std::array is used), the headers that json.hpp
already provides (abi_config, abi_macros, input_adapters, json_pointer,
cpp_future, string_concat, value_t, json_fwd), and <version> for
std::nullptr_t, and removing <cstddef>.

- include <array>
- keep <cstddef> (nullptr_t, size_t; IWYU attributes them to <version> and <cstring>)
- tell IWYU not to suggest the headers that json.hpp provides: the amalgamated
  json_view.hpp only includes json.hpp, so including them here would duplicate
  their definitions

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:06 +02:00
Niels Lohmann f7c1b3495a Avoid GCC useless-cast warnings in the integer index tests
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:05 +02:00
Niels Lohmann 8ed4b496b3 Make json_view.hpp pass include-what-you-use
Mark the includes that are needed by design (json.hpp, the macro
unscope, <tuple> for the tuple_size specialization), take size_t from
<cstring>, and drop the forward declaration of basic_json_document that
the friend declaration makes redundant.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:04 +02:00
Niels Lohmann 52691713dc Do not force-inline the view's functions on MSVC
__forceinline makes MSVC report C4714 for function templates it cannot
inline (get<std::string>), an error under /WX. The forced inlining is
only a performance hint, so use plain inline there.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:04 +02:00
Niels Lohmann decf6de9c7 Return the first member of duplicate keys from lookups again
Looking up the last member of a duplicate key cannot stop at a match, so
every lookup scanned the whole object (1.6 to 3.4 times slower for small
objects). operator[](key), at, find, value, contains, count, and JSON
pointer resolution return the first member again, as yyjson and simdjson
do; materialize() and get<map>() keep the last value, as parse().

The documentation says so in the feature page and on each lookup page,
and explains how to get the value parse() would give. The integer index
templates and the discarded chaining of operator[] stay.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:03 +02:00
Niels Lohmann 10ec5a0381 Test discarded views with is_discarded() in the operator[] docs and examples
The explicit conversion to bool of basic_json_view is gone.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:02 +02:00
Niels Lohmann f85c4bf8b6 Use named documents in the json_view tests that called root() on a temporary
root() of an rvalue document is deleted, because the views would dangle.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:01 +02:00
Niels Lohmann 5badf2eac5 Replace the removed operator bool of basic_json_view in the header and its tests
A view is tested with is_discarded(); the lookups in at(), value() and
contains(json_pointer) and the unit tests no longer rely on the explicit
conversion to bool.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:28:00 +02:00
Niels Lohmann 4ebac0263e Make view lookups last-wins and chained access safe
* Lookups (operator[], at, find, contains, count, value, JSON pointers)
  return the last member of a duplicate key, as materialize() and
  parse() keep it.
* operator[] on a discarded view returns a discarded view instead of
  throwing, so v["a"]["b"] is safe for a missing "a".
* operator[] and at() take any integer type (not only int and size_t),
  fixing ambiguous calls with unsigned, long, std::int64_t, ...
* Fix the operator[] documentation, which claimed a discarded view for
  a type mismatch where type_error.305 is thrown.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:59 +02:00
Niels Lohmann 041a561e56 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-11 10:27:58 +02:00
Niels Lohmann e5076dabdc Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:58 +02:00
Niels Lohmann 41fd507e8f Silence a clang-tidy use-after-move finding in the json_view test
const_text is const, so std::move does not move from it; the second call
is part of the const rvalue test.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:57 +02:00
Niels Lohmann 10d36d3af2 Read the node array base after emit() in the view builder's open()
emit() moves the node array when it grows, and the subtraction read base
in the same expression, so the order was unspecified. MSVC Release builds
without forced inlining read the old base; the container index then
pointed outside the array and close() wrote out of bounds.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:56 +02:00
Niels Lohmann eeae3e9121 Make json_view.hpp pass include-what-you-use
ci_single_binaries runs IWYU with --error on every header. For json_view.hpp
it suggested adding <array> (std::array is used), the headers that json.hpp
already provides (abi_config, abi_macros, input_adapters, json_pointer,
cpp_future, string_concat, value_t, json_fwd), and <version> for
std::nullptr_t, and removing <cstddef>.

- include <array>
- keep <cstddef> (nullptr_t, size_t; IWYU attributes them to <version> and <cstring>)
- tell IWYU not to suggest the headers that json.hpp provides: the amalgamated
  json_view.hpp only includes json.hpp, so including them here would duplicate
  their definitions
- export json.hpp, keep macro_unscope.hpp, and drop the unused forward declaration of the document class

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:55 +02:00
Niels Lohmann 4a4aa8cfc0 Make max_input_size a function (GCC -Wunused-const-variable)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:54 +02:00
Niels Lohmann 1d948b31e9 Check the steps of the deep-nesting test separately
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:54 +02:00
Niels Lohmann c0dbdec1ca Suppress Flawfinder's read() finding on the deleted overload
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:53 +02:00
Niels Lohmann bf0a485c9d Annotate intentional patterns in unit-json_view.cpp for clang-tidy
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:52 +02:00
Niels Lohmann 5b5e0c2750 Fix clang-tidy findings in unit-json_view_builder.cpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:51 +02:00
Niels Lohmann 0c30a9b6de Give document_data a user-provided constructor
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:50 +02:00
Niels Lohmann 938e0d16ff Fuzz json_document with exact-size buffers and parse options
The fuzzer only parsed a std::string with default options. Also parse an
exact-size byte vector, which has no NUL after its last byte and takes the
bounds-checked path, and derive ignore_comments and ignore_trailing_commas
from the first input byte, comparing against json::parse and json::accept
with the same options.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:50 +02:00
Niels Lohmann a5a6ff6b7c Align the banner comment of json_view.hpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:49 +02:00
Niels Lohmann f0168aaa5f Remove the unused legacy_discarded_value_comparison from abi_config
Nothing reads it: the view does not compare values.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:48 +02:00
Niels Lohmann a532412bb2 State the exact input size limit of json_document
The check rejects inputs of 0xFFFFFFF0 bytes or more, but the exception
message and the documentation said 4 GiB. Name the limit once
(max_input_size), and state 4 GiB minus 16 bytes in the message and the
documentation. Test the limit with a container that only claims the size.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:47 +02:00
Niels Lohmann b009db69b3 Check the node array size for overflow
reserve(n) and the growth of the index computed n * sizeof(node) without a
check, which wraps around on 32-bit targets for inputs of about 1 GiB and
allocates a too small array. Throw std::bad_alloc for a count beyond the
address space and clamp the growth step to it.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:46 +02:00
Niels Lohmann 95704857ba Store node integers by halves on big-endian targets
The non-little-endian path of the node writer wrote the integer's native
word over len and next, so len got the high half there. Compose and split
the value explicitly (len is the low half, next the high half); the
little-endian path stays a plain memcpy.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:46 +02:00
Niels Lohmann 6661390b23 Delete json_document::root() on temporary documents
auto v = json_document::parse(text).root() compiled and left the view
dangling. Delete the overload for rvalue documents, take a named document
in the tests, and document the lifetime rule.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:45 +02:00
Niels Lohmann 240dae052f Remove the conversion to bool from json_view
explicit operator bool meant "refers to a value", which silently differs
from what a basic_json converts to. Use !v.is_discarded() instead.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:44 +02:00
Niels Lohmann 4b1eddb286 Copy const rvalue strings and document the accepted inputs
json_document::parse(std::move(const_string)) failed to compile with
"no matching read_kind": only a non-const rvalue std::string can be moved
from. Treat a const rvalue as a copied byte container.

parse() does not accept everything BasicJsonType::parse() does: a FILE*
and pointers to or arrays of wide characters are rejected at compile time.
List the supported inputs instead.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:43 +02:00
Niels Lohmann 45ce9b51f5 Reject integer lengths in json_document::parse
parse(ptr, len) compiled: len converted to allow_exceptions, and ptr was
read as a C string, past the end of a buffer without a terminating NUL.
Delete the overloads of parse, parse_copy, accept, and read that take an
integer other than bool where the flags are expected.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:42 +02:00
Niels Lohmann 36626efe9f 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-11 10:27:42 +02:00
Niels Lohmann 7bb286df21 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-11 10:27:41 +02:00
Niels Lohmann 1d59a0f4a6 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-11 10:27:40 +02:00
Niels Lohmann 2ad81e9a89 Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:39 +02:00
Niels Lohmann 9783b2db58 Silence MSVC C4127 for a platform-constant check in the to_chars test
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:38 +02:00
Niels Lohmann 1f5c61ca7d Credit Zmij's authors in to_chars.hpp, the README, and the license page
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:37 +02:00
Niels Lohmann 26383cfcb8 Select the Zmij conversion by a trait, not by the double overload
The non-template overloads for double asserted binary64 doubles wherever json.hpp was included, so the library no longer compiled where double is not IEEE 754 binary64 (AVR, -fshort-double). A trait now picks Zmij for any binary64 type, including a long double of that format (MSVC, Apple Arm), and Grisu2 for the others. Remove the unused write_short_decimal, powers_of_ten_16, zmij::decimal, zmij::to_decimal, and shortest_digits(double).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:37 +02:00
Niels Lohmann bf59f687c3 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-11 10:27:36 +02:00
Niels Lohmann 2dc6471968 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-11 10:27:35 +02:00
Niels Lohmann fb02078fe1 Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:34 +02:00
Niels Lohmann d99a485ce7 Mark the unsigned long of the MSVC bit scans for cpplint
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:33 +02:00
Niels Lohmann 80bfa0ac73 Fix clang-tidy 22 findings in unit-class_lexer.cpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:32 +02:00
Niels Lohmann ae8be9c853 Reword float conversion notes for the string type and number_float_t docs
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:32 +02:00
Niels Lohmann ba6f158378 Load string scan words with memcpy and use MSVC bit-scan intrinsics
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:31 +02:00
Niels Lohmann 6c82661a3d 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-11 10:27:30 +02:00
Niels Lohmann 422684995c 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-11 10:27:29 +02:00
Niels Lohmann c59ad95252 Expect type_error.321 for deep discarded values in the BON8 writer test (#5807)
#5806 added the test while #5802 made to_bon8 reject discarded values; both
merged, so the test failed on develop.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 10:27:16 +02:00
Niels LohmannandClaude Opus 5.5 b38a2c9177 Stop the BON8 writer overflowing the stack on deep values (#5806)
* Stop the BON8 writer overflowing the stack on deep values

to_bon8() recursed once per nesting level, so a value the iterative
BON8 reader accepts (e.g. ~24k nested one-element arrays) crashed on
the way back out. #5781 bounded the CBOR, MessagePack, and UBJSON/BJData
writers, but BON8 was merged before it and was not covered.

Apply the same scheme: recurse for the first recursion_depth_limit()
levels, then finish the value with write_bon8_iterative, which keeps
the open containers on a heap stack (reusing binary_container_frame)
and writes the 0xFE closer when it leaves a container with more than
four elements. The output is byte-for-byte unchanged.

Fixes https://issues.oss-fuzz.com/issues/572238015

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

* Merge the array and object branches of the BON8 iterative writer

write_bon8_iterative and write_bon8_value_or_push handled arrays and
objects in separate branches that repeated the end-of-container check,
the 0xFE closer and the marker computation. Share those parts and branch
only where arrays and objects really differ. The output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hz7VJi1FTKr6gpseLErbbS
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 08:24:35 +02:00
Niels Lohmann eb8899a29c Restore v3.12.0 support for custom object key types (#5795)
* Restore v3.12.0 support for custom object key types

Custom object_t types whose key_type is not string_t compiled with
v3.12.0 for several APIs that unreleased changes broke:

- to_bson failed for every custom key type (#5553 kept a const string_t*
  to the key); the nested entry's header is now written where the entry
  is found.
- Copying deep values (and parse, merge_patch, update, insert) required
  operator== on keys (#5389); keys without one are now paired via find().
- to_cbor/to_msgpack required an implicit conversion to string_t (#5746,
  #5328); keys without one go through a temporary basic_json again.
- at() required a conversion to string_t for its error message (#5727);
  other keys are passed to concat() unchanged again.

The new unit-custom-object-key-type.cpp covers five key types with
different capabilities.

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

* Use the with_object_t alias for the custom object key test types

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

* Avoid floating-point equality in custom key type test

GCC with -Werror=float-equal rejects comparing the double value with ==.

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

* Write the head of nested BSON elements in one helper

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

* Suppress bugprone-return-const-ref-from-parameter in key_for_message

The reference is only passed to concat() within the full-expression that
holds the key, like the similar helpers in binary_writer.hpp.

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

* Make the value of the custom test key types private

clang-tidy (cppcoreguidelines-non-private-member-variables-in-classes)
rejects the protected member; the derived key types use a protected
accessor instead.

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

* Pass keys with data() and size() unchanged into the at() miss message

key_for_message() converted every key that string_t can be constructed
from, so a miss on a string_t or string_view key copied it before
concat() copied it again. Keys that concat() can append through data()
and size() are now passed through; only other keys (string literals,
key types that just convert to string_t) are converted.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 08:24:31 +02:00
Niels Lohmann 11ef352511 Point users to update(…, true), JSON Pointer defaults, and built-in std::optional (#5804)
A code search of client code found many hand-written versions of
functionality the library already has: recursive object merges
(update(j, true) since 3.10.5), dotted-path getters (value() and
contains() with a JSON Pointer), get_or helpers (value() throws for a
member that is present but null), and adl_serializer specializations
for std::optional (supported since 3.12.0).

- modifying_values.md: describe both modes of update(), add a
  defaults + user settings recipe, and stop recommending Merge Patch
  for recursive merges.
- merge_patch.md: note that null deletes keys, so a merge patch is not
  a general deep merge; link update().
- default_value.md: add "Nested values" (value/contains with a JSON
  Pointer, building a pointer from a dotted path with operator/=) and
  a warning that null and mistyped members are not missing.
- value.md: note that a null member is converted, not replaced by the
  default.
- json_pointer.md: link value/contains/at with JSON Pointers.
- arbitrary_types.md: note that std::optional needs no serializer.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 08:22:10 +02:00
Niels Lohmann 74a03dec84 Throw type_error.321 for discarded values in to_bon8 (#5802)
write_bon8_value silently skipped discarded values, but the array/object
count marker still counted them, so [1, discarded] produced 82 91: a marker
announcing two elements followed by one. Throw type_error.321 like the other
binary writers do, at any nesting level.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 08:22:00 +02:00
Niels Lohmann 6197341a21 Clean up non-code files (#5801)
* Clean up README, contribution guide, and repository metadata

- REUSE.toml: fix the Hedley path and SPDX id (CC0-1.0), mark the docset
  icons as the public-domain JSON logo
- CITATION.cff: v3.12.0 was released on 2025-04-11
- FILES.md: list all workflows, describe the Meson option defaults
- README: ctest -LE, table of contents, typos, stale Android/MinGW advice,
  moved links, merge duplicate Thanks entries, list the analysis tools
  used in CI
- CONTRIBUTING: iterative parser, json_literals.hpp is generated, links
- .gitignore: backups and release outputs; .gitattributes: mark
  generated files
- labeler: label other build systems and .github documentation
- MODULE.bazel: add the module version

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

* Clean up CI, CMake, Makefile, and Bazel files

- CMakeLists.txt: avoid VERSION_GREATER_EQUAL, which CMake < 3.7 lacks
- ci.cmake: test JSON_DisableTupleReferenceConversion in ci_cmake_flags,
  remove unused variables and unreachable per-compiler targets, look up
  Clang tools consistently, forward CMAKE_CXX_FLAGS to ci_module_cpp20,
  format json_literals.hpp and remove backups in ci_test_amalgamation
- BUILD.bazel: add json_literals.hpp to the single-header target
- workflows: format json_literals.hpp before copying it, drop the obsolete
  natvis --version plumbing, name natvis and macro_builder in failure
  messages, drop the duplicate amalgamation job, install Valgrind only
  where needed, republish docs on version bumps, fix stale names
- Makefile: complete .PHONY and help, check-amalgamation always restores
  the checked-in files, natvis uses its own venv, macro_builder_check
  installs astyle, clean removes the fuzzer binaries
- remove tools/amalgamate/config_json_view.json (json_view.hpp is not on
  develop yet)

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

* Fix inaccuracies in the documentation

- version history: json_base_class_t (3.11.3), JSON_HAS_CPP_11 (3.10.0),
  JSON_HAS_RANGES exclusions, define-type macros, ABI tags
- releases: 3.12.0 raised the minimum CMake version
- from_*: the (ptr, len) overloads are deleted, not removed, in 4.0.0
- contains/count/find: document the deleted integral overloads
- add JSON_HAS_RANGE_VIEW_CONVERSION and list the JSON_HAS_* macros in
  the macro overview
- mention BON8 and error_handler where binary formats are listed
- broken links, outdated URLs, warning count, Hunter v0.26.12
- copy_markdown_source hook: expand snippets in the Markdown copies

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

* Pass /EHsc to the Windows C++20 module build

ci_module_cpp20 now forwards CMAKE_CXX_FLAGS to the module build. The
Windows workflow sets CMAKE_CXX_FLAGS, which replaces CMake's MSVC
defaults including /EHsc, so <chrono> failed with C4530 under /WX.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 08:21:51 +02:00
Niels Lohmann 2cca04ae6f Report one-character non-numeric array indices like longer ones (#5800)
* Report one-character non-numeric array indices like longer ones

A JSON pointer reference token that is not a number but has only one
character (e.g. "/a/x") was reported as out_of_range.404 ("unresolved
reference token"), because the "is not a number" check only ran for
tokens longer than one character; "/a/xy" got parse_error.109. Both now
throw parse_error.109. "-" and the empty token are still reported as
out_of_range.404. As a consequence, value(json_pointer, default) on an
array now throws for "/x" as it already did for "/xy".

Also document why ordered_map::erase's destroy/placement-new loop on
pair<const Key, T> is kept despite [basic.life]/8 before C++20.

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

* Document the one-character array index change

Add 3.13.0 version-history entries to at, operator[], value, patch,
patch_inplace, and unflatten, and describe in exceptions.md which array
indices throw parse_error.109 and which out_of_range.404.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 08:21:41 +02:00
Niels Lohmann 1649d9eda4 Use and extend the detail helpers to remove duplicated code (#5783)
* Use and extend the detail helpers to remove duplicated code

Library:
- binary_reader: format bytes with hex_byte() instead of snprintf
- add throw_type_must_be() for the 20 copies of type_error.302
- binary_reader: add last_byte_error()/unexpected_byte() for the 32
  "parse error at the last read byte" sites (replaces bon8_error)
- json_sax: add check_container_size() for out_of_range.408 and
  diagnostic_positions::set_container_start/_end()
- json_pointer: add throw_no_parent() (405) and throw_unresolved() (404)

Tests:
- unit-class_parser uses the shared utils::SaxCountdown
- move SaxEventLogger (and its ExitAfter* variants) from unit-class_parser
  and unit-deserialization into the new tests/src/test_sax.hpp

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

* Factor out more repeated error paths and test boilerplate

Library:
- add throw_cannot_use_with() for the 34 copies of type_error.304-312
  "cannot use X with Y"
- iter_impl: add throw_cannot_get_value() (invalid_iterator.214)
- parser: add syntax_error() for the 12 parse_error.101 sites
- ordered_map: share the four at() bodies via at_impl()
- json_sax_dom_callback_parser: add pop_container() for end_object()
  and end_array()
- binary_reader: build the two UBJSON/BJData length-type messages with
  concat() and last_byte_error()

Tests:
- move same_value(), the NDEBUG guard, and step 0 (parse without
  exceptions) of the seven fuzzer drivers into tests/src/fuzzer_common.hpp

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

* Name the exception ids and address review comments

Add detail::exception_id, a scoped enum with one named enumerator per
documented exception id, and use it for every id in the library. The
create() functions get an overload for it; the int overloads stay for
user code.

Following the review of #5783: add binary_reader::invalid_byte() and
length_type_error(), basic_json::throw_subscript_wrong_type(), move the
fuzzer includes and the using-declaration into fuzzer_common.hpp, and
rename test_sax.hpp to sax_event_loggers.hpp.

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

* Silence -Wweak-vtables for the SAX event loggers

The loggers moved from anonymous namespaces in the test files into
sax_event_loggers.hpp, so clang now warns that their vtables are
emitted in every translation unit.

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

* Silence MSVC 2015 C4100 in parser::syntax_error for static SAX::parse_error

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

* Inline invalid_byte() into its call sites

The wrapper only fixed the message string of unexpected_byte(), which is
the same kind of per-argument helper that was declined for
throw_type_must_be(). Call unexpected_byte("invalid byte", ...) directly.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 08:21:13 +02:00
Niels Lohmann f8b47ff6f6 Check the URL scheme before downloading in generate_docset.py (#5803)
Codacy flagged two Bandit findings in the docset generator added in
#5799: B310 (urlopen with an unchecked scheme) and B506 (yaml.load).
download() now rejects anything but http(s) URLs before opening them,
and the yaml.load call is marked, since its Loader derives from
yaml.SafeLoader. The SHA-1 used to name downloaded files is marked as
not used for security.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-10 16:21:53 +02:00
Niels Lohmann 07ec1a4e31 Generate the docset index and pages with Python (#5799)
Replace the hand-maintained docs/docset/docSet.sql and the bash/sed
Makefile recipe with docs/docset/generate_docset.py:

- The search index is generated from the mkdocs.yml nav and each page's
  H1 and declaration. Pages documenting several entities (e.g.
  JSON_HAS_CPP_11..26) get one entry per name; all non-API pages become
  guides. New API pages no longer need a manual entry.
- Page titles are set from the index names.
- The docset is self-contained: the mermaid loader no longer points to
  https://json.nlohmann.me/assets/..., the repository widget no longer
  queries api.github.com, remaining remote images are downloaded, and
  the build fails if any remote resource load remains.
- The CSS that hides the site navigation now uses Material's classes;
  the element selectors lost against them, so the header was shown.

check_structure.py's docset check is replaced by running the generator
in `make style_check`.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-10 12:10:11 +02:00
429 changed files with 36884 additions and 7504 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# generated files are collapsed in diffs and excluded from language statistics
single_include/** linguist-generated
nlohmann_json.natvis linguist-generated
+1 -1
View File
@@ -1,5 +1,5 @@
# JSON for Modern C++ was originally written by Niels Lohmann. # JSON for Modern C++ was originally written by Niels Lohmann.
# Since 2013, over 250 contributors have helped to improve the library. # Since 2013, over 400 contributors have helped to improve the library.
# This CODEOWNERS file is only to make sure that @nlohmann is requested # This CODEOWNERS file is only to make sure that @nlohmann is requested
# for a code review in case of a pull request. # for a code review in case of a pull request.
+19 -24
View File
@@ -98,7 +98,7 @@ $ ctest --test-dir build -j 10
The test suite should report: The test suite should report:
``` ```
100% tests passed, 0 tests failed out of 98 100% tests passed, 0 tests failed out of <number of tests>
``` ```
#### Add tests #### Add tests
@@ -108,16 +108,9 @@ The tests are located in [`tests/src/unit-*.cpp`](https://github.com/nlohmann/js
are structured along the features of the library or the nature of the tests. Usually, it should be clear from the are structured along the features of the library or the nature of the tests. Usually, it should be clear from the
context which existing file needs to be extended, and only very few cases require creating new test files. context which existing file needs to be extended, and only very few cases require creating new test files.
When fixing a bug, edit `unit-regression3.cpp` and add a section referencing the fixed issue. Tests that need C++17 or When fixing a bug, edit `unit-regression3.cpp` and add a section referencing the fixed issue.
C++20 go into `unit-regression3-cpp17.cpp` or `unit-regression3-cpp20.cpp` instead, so the large file is not rebuilt `unit-regression2.cpp` holds the older tests; the two files exist because a single one grew large enough for the
for every C++ standard. `unit-regression2.cpp` holds the older tests; the two files exist because a single one grew MinGW linker to fail relocating it, so please keep adding to the smaller file rather than growing the larger one.
large enough for the MinGW linker to fail relocating it, so please keep adding to the smaller file rather than growing
the larger one.
To keep compile times down, several test files are compiled together as one translation unit. This sets a few rules
for test files, such as giving file-scope helpers file-specific names. See the README in the
[`tests`](https://github.com/nlohmann/json/tree/develop/tests) folder for how the tests are built and what to keep in
mind when adding them.
#### Exceptions #### Exceptions
@@ -156,14 +149,17 @@ make build -C docs/mkdocs # strict build: fails on broken links, anchor
make check_mermaid -C docs/mkdocs # checks the Mermaid diagrams (requires Node.js) make check_mermaid -C docs/mkdocs # checks the Mermaid diagrams (requires Node.js)
``` ```
A new API page also needs an entry in [`docs/docset/docSet.sql`](https://github.com/nlohmann/json/blob/develop/docs/docset/docSet.sql), The search index of the docset is generated from [`mkdocs.yml`](https://github.com/nlohmann/json/blob/develop/docs/mkdocs/mkdocs.yml)
the search index of the docset; `make build` reports missing entries. and each page's title (H1) and declaration by
[`docs/docset/generate_docset.py`](https://github.com/nlohmann/json/blob/develop/docs/docset/generate_docset.py);
`make build` reports API pages that cannot be classified.
### Amalgamate the source code ### Amalgamate the source code
The single-header files The single-header files
[`single_include/nlohmann/json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) and [`single_include/nlohmann/json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp),
[`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) [`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp), and
[`single_include/nlohmann/json_literals.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_literals.hpp)
are **generated** from the source files in the are **generated** from the source files in the
[`include/nlohmann` directory](https://github.com/nlohmann/json/tree/develop/include/nlohmann). **Do not** edit the [`include/nlohmann` directory](https://github.com/nlohmann/json/tree/develop/include/nlohmann). **Do not** edit the
files directly; instead, modify the include/nlohmann sources and regenerate the files by executing: files directly; instead, modify the include/nlohmann sources and regenerate the files by executing:
@@ -186,7 +182,7 @@ The amalgamation check in CI fails if any of these generated files is out of dat
## Recommended documentation ## Recommended documentation
- The library’s [README file](https://github.com/nlohmann/json/blob/master/README.md) is an excellent starting point to - The library’s [README file](https://github.com/nlohmann/json/blob/develop/README.md) is an excellent starting point to
understand its functionality. understand its functionality.
- The [documentation page](https://json.nlohmann.me) is the reference documentation of the library. - The [documentation page](https://json.nlohmann.me) is the reference documentation of the library.
- [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259) is the reference for the JavaScript Object Notation (JSON) - [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259) is the reference for the JavaScript Object Notation (JSON)
@@ -225,9 +221,9 @@ feature macros then allows users to test their code against the library in the n
### Break C++11 language conformance ### Break C++11 language conformance
This library is designed to work with C++11 and later. This means that any This library is designed to work with C++11 and later. This means that any
[supported C++11 compiler](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers) should compile [supported C++11 compiler](https://github.com/nlohmann/json/blob/develop/README.md#supported-compilers) should compile
the library without problems. Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual the library without problems. Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual
Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. C++ 2013 and earlier are known not to work due to missing or incomplete C++11 support.
Please do not add features that do not work with the mentioned supported compilers. Please guard features from C++14 and Please do not add features that do not work with the mentioned supported compilers. Please guard features from C++14 and
later against the respective [`JSON_HAS_CPP_14`](https://json.nlohmann.me/api/macros/json_has_cpp_11/) macros. later against the respective [`JSON_HAS_CPP_14`](https://json.nlohmann.me/api/macros/json_has_cpp_11/) macros.
@@ -243,12 +239,11 @@ extension.
The following areas really need contribution and are always welcomed: The following areas really need contribution and are always welcomed:
- Extending the **continuous integration** toward more exotic compilers such as Android NDK, Intel's Compiler, or the - Extending the **continuous integration** toward more exotic compilers such as Android NDK, Intel's Compiler, or the
bleeding-edge versions Clang. bleeding-edge versions of Clang.
- Improving the efficiency of the **JSON parser**. The current parser is implemented as a naive recursive descent parser - Improving the efficiency of the **JSON parser**. The current parser is a hand-written iterative parser that keeps an
with hand-coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That explicit stack instead of recursing, with hand-coded string handling. Speeding up the lexer or the value construction
said, parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep would be appreciated. Parser generators like Bison or ANTLR do not play nice with single-header files -- I really
the parser inside the `json.hpp` header, and I am not aware of approaches similar to [`re2c`](http://re2c.org) for would like to keep the parser inside the `json.hpp` header.
parsing.
- Extending and updating existing **benchmarks** to include (the most recent version of) this library. Though efficiency - Extending and updating existing **benchmarks** to include (the most recent version of) this library. Though efficiency
is not everything, speed and memory consumption are very important characteristics for C++ developers, so having is not everything, speed and memory consumption are very important characteristics for C++ developers, so having
proper comparisons would be interesting. proper comparisons would be interesting.
+2 -2
View File
@@ -52,7 +52,7 @@ body:
If possible, provide a small and self-contained example that triggers If possible, provide a small and self-contained example that triggers
the bug. Please understand that we cannot analyze and debug large code the bug. Please understand that we cannot analyze and debug large code
bases. Please do not paste screenshots here. bases. Please do not paste screenshots here.
render: Shell render: cpp
- type: textarea - type: textarea
id: output id: output
attributes: attributes:
@@ -79,7 +79,7 @@ body:
description: > description: >
Which version of the library did you use? If it is a released version, Which version of the library did you use? If it is a released version,
please enter the version number (e.g., 3.12.0). Otherwise, please enter please enter the version number (e.g., 3.12.0). Otherwise, please enter
the commit hash. If you got the library from another source as the the commit hash. If you got the library from another source than the
GitHub repository (e.g., via a package manager), please also state GitHub repository (e.g., via a package manager), please also state
this. this.
validations: validations:
+29
View File
@@ -21,6 +21,17 @@ labels:
files: files:
- "cmake/.*" - "cmake/.*"
# other build systems
- label: "CMake"
files:
- "(meson\\.build|meson_options\\.txt|BUILD\\.bazel|MODULE\\.bazel|Package\\.swift)"
- label: "documentation"
files:
- ".github/ISSUE_TEMPLATE/.*"
- ".github/config\\.yml"
- ".github/(CONTRIBUTING|SECURITY|CODE_OF_CONDUCT|PULL_REQUEST_TEMPLATE)\\.md"
- label: "CI" - label: "CI"
files: files:
- ".github/workflows/.*" - ".github/workflows/.*"
@@ -45,6 +56,24 @@ labels:
- label: "aspect: binary formats" - label: "aspect: binary formats"
title: "(?i)(bson|cbor|msgpack|messagepack|ubjson|bjdata|bon8|binary format)" 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/json_view_test_helpers\\.hpp"
- "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" - label: "python"
files: files:
- "\\.py$" - "\\.py$"
+11 -14
View File
@@ -83,8 +83,7 @@ jobs:
# byte for byte), so there is nothing to gain from checking out a # byte for byte), so there is nothing to gain from checking out a
# separate copy, and doing so would make this step fail on a PR # separate copy, and doing so would make this step fail on a PR
# that adds support for a new dispatch table until that PR itself # that adds support for a new dispatch table until that PR itself
# merges to develop, the same way generate_natvis.py's --version # merges to develop.
# requirement briefly did.
TMPDIR=$(mktemp -d ./macro_builder_check.XXXXXX) TMPDIR=$(mktemp -d ./macro_builder_check.XXXXXX)
c++ -std=c++11 tools/macro_builder/main.cpp -o "$TMPDIR/macro_builder" c++ -std=c++11 tools/macro_builder/main.cpp -o "$TMPDIR/macro_builder"
"$TMPDIR/macro_builder" > "$TMPDIR/paste.hpp" "$TMPDIR/macro_builder" > "$TMPDIR/paste.hpp"
@@ -117,13 +116,15 @@ jobs:
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s . 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 . 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/ # the header list of the Bazel "json" target must match the files in include/
cmake -P cmake/scripts/gen_bazel_build_file.cmake cmake -P cmake/scripts/gen_bazel_build_file.cmake
${{ github.workspace }}/venv/bin/astyle --project=tools/astyle/.astylerc --suffix=none --quiet \ ${{ 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 # 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 # about the missing path and silently drop its files from the check
@@ -138,17 +139,13 @@ jobs:
${{ github.workspace }}/venv/bin/astyle --project=tools/astyle/.astylerc --suffix=none --quiet \ ${{ github.workspace }}/venv/bin/astyle --project=tools/astyle/.astylerc --suffix=none --quiet \
$(find $SOURCE_DIRS -type f \( -name '*.hpp' -o -name '*.cpp' -o -name '*.cu' \) -not -path 'tests/thirdparty/*' -not -path 'tests/abi/include/nlohmann/*' | sort) $(find $SOURCE_DIRS -type f \( -name '*.hpp' -o -name '*.cpp' -o -name '*.cu' \) -not -path 'tests/thirdparty/*' -not -path 'tests/abi/include/nlohmann/*' | sort)
# json_literals.hpp is copied verbatim from the (now formatted) include/
# directory, like `make amalgamate` does
cp include/nlohmann/json_literals.hpp $INCLUDE_DIR/json_literals.hpp
- name: Regenerate nlohmann_json.natvis - name: Regenerate nlohmann_json.natvis
run: | run: |
cd $MAIN_DIR cd $MAIN_DIR
# Pass --version explicitly so this step also works with the tool
# copy from develop before this repository's own generate_natvis.py
# learns to derive the version itself: the older script requires
# --version, and the newer one accepts it as an explicit override.
ABI_MACROS=include/nlohmann/detail/abi_macros.hpp
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 # The template is what this check verifies the committed natvis
# file against, so take it from this PR rather than from the # file against, so take it from this PR rather than from the
# develop checkout: generate_natvis.py loads the template from its # develop checkout: generate_natvis.py loads the template from its
@@ -156,7 +153,7 @@ jobs:
# template could never pass. Like the macro_builder step above, # template could never pass. Like the macro_builder step above,
# this only renders PR content in a job without credentials. # this only renders PR content in a job without credentials.
cp tools/generate_natvis/nlohmann_json.natvis.j2 $NATVIS_TOOL_DIR/ 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 python3 $NATVIS_TOOL_DIR/generate_natvis.py $MAIN_DIR
- name: Build patch and check for differences - name: Build patch and check for differences
id: diff id: diff
@@ -165,7 +162,7 @@ jobs:
mkdir -p ${{ github.workspace }}/patch mkdir -p ${{ github.workspace }}/patch
git diff --patch --no-color > ${{ github.workspace }}/patch/amalgamation.patch git diff --patch --no-color > ${{ github.workspace }}/patch/amalgamation.patch
if [ -s ${{ github.workspace }}/patch/amalgamation.patch ]; then if [ -s ${{ github.workspace }}/patch/amalgamation.patch ]; then
echo "The source code has not been amalgamated/formatted correctly or BUILD.bazel is out of date. Diff:" echo "The source code has not been amalgamated/formatted correctly, or BUILD.bazel, nlohmann_json.natvis, or the macro_builder tables in macro_scope.hpp are out of date ('make amalgamate BUILD.bazel natvis' fixes all but the tables, see tools/macro_builder/README.md). Diff:"
cat ${{ github.workspace }}/patch/amalgamation.patch cat ${{ github.workspace }}/patch/amalgamation.patch
echo "has_diff=true" >> "$GITHUB_OUTPUT" echo "has_diff=true" >> "$GITHUB_OUTPUT"
else else
@@ -96,7 +96,7 @@ jobs:
issue_number: issue_number, issue_number: issue_number,
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
body: '## 🔴 Amalgamation check failed! 🔴\nThe source code has not been amalgamated and/or formatted correctly, or `BUILD.bazel` is out of date.' body: '## 🔴 Amalgamation check failed! 🔴\nThe source code has not been amalgamated and/or formatted correctly, or `BUILD.bazel`, `nlohmann_json.natvis`, or the macro_builder tables in `macro_scope.hpp` are out of date. `make amalgamate BUILD.bazel natvis` fixes all but the tables (see `tools/macro_builder/README.md`).'
+ (hasPatch ? '\n\n📎 A ready-to-apply patch is attached to the [failed workflow run](' + runUrl + ') as the `amalgamation-patch` artifact.' + (hasPatch ? '\n\n📎 A ready-to-apply patch is attached to the [failed workflow run](' + runUrl + ') as the `amalgamation-patch` artifact.'
+ ' Download it, then apply it locally from the repository root with:' + ' Download it, then apply it locally from the repository root with:'
+ '\n\n```shell\ngit apply amalgamation.patch\n```\n\n' + '\n\n```shell\ngit apply amalgamation.patch\n```\n\n'
@@ -15,6 +15,7 @@ on:
- .github/SECURITY.md - .github/SECURITY.md
- cmake/clang_flags.cmake - cmake/clang_flags.cmake
- cmake/gcc_flags.cmake - cmake/gcc_flags.cmake
- include/nlohmann/detail/abi_macros.hpp
- tests/fmt_formatter/project/main.cpp - tests/fmt_formatter/project/main.cpp
- tools/astyle/.astylerc - tools/astyle/.astylerc
workflow_dispatch: workflow_dispatch:
+3 -2
View File
@@ -109,7 +109,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
target: [ci_test_amalgamation, ci_test_single_header, ci_cppcheck, ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_reuse_compliance, ci_test_valgrind] target: [ci_test_single_header, ci_cppcheck, ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_reuse_compliance, ci_test_valgrind]
steps: steps:
- name: Harden Runner - name: Harden Runner
uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1 uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
@@ -117,6 +117,7 @@ jobs:
egress-policy: audit egress-policy: audit
- name: Install Valgrind - name: Install Valgrind
if: matrix.target == 'ci_test_valgrind'
run: sudo apt-get update ; sudo apt-get install -y valgrind run: sudo apt-get update ; sudo apt-get install -y valgrind
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: with:
@@ -279,7 +280,7 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Get latest CMake and ninja - name: Get latest CMake and ninja
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2 uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
- name: Set env FORCE_STDCPPFS_FLAG for clang 7 / 8 / 9 / 10 - name: Disable filesystem support (std::filesystem is unusable) for clang 7 / 8 / 9 / 10
run: echo "JSON_FORCED_GLOBAL_COMPILE_OPTIONS=-DJSON_HAS_FILESYSTEM=0;-DJSON_HAS_EXPERIMENTAL_FILESYSTEM=0" >> "$GITHUB_ENV" run: echo "JSON_FORCED_GLOBAL_COMPILE_OPTIONS=-DJSON_HAS_FILESYSTEM=0;-DJSON_HAS_EXPERIMENTAL_FILESYSTEM=0" >> "$GITHUB_ENV"
if: ${{ matrix.compiler == '7' || matrix.compiler == '8' || matrix.compiler == '9' || matrix.compiler == '10' }} if: ${{ matrix.compiler == '7' || matrix.compiler == '8' || matrix.compiler == '9' || matrix.compiler == '10' }}
- name: Run CMake - name: Run CMake
+4 -2
View File
@@ -187,7 +187,7 @@ jobs:
- name: Test - name: Test
run: cd build ; ctest -j 10 -C Debug --output-on-failure run: cd build ; ctest -j 10 -C Debug --output-on-failure
clang-cl-12: clang-cl:
runs-on: windows-2022 runs-on: windows-2022
strategy: strategy:
matrix: matrix:
@@ -217,8 +217,10 @@ jobs:
uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2 uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2
with: with:
cmakeVersion: 4.3.4 cmakeVersion: 4.3.4
# CMAKE_CXX_FLAGS replaces CMake's MSVC defaults (which include /EHsc), and
# ci_module_cpp20 forwards it to the module build, so list /EHsc explicitly
- name: Run CMake (Debug) - name: Run CMake (Debug)
run: cmake -S . -B build -G "Visual Studio 17 2022" -DJSON_CI=ON -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX" run: cmake -S . -B build -G "Visual Studio 17 2022" -DJSON_CI=ON -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /EHsc /W4 /WX"
- name: Build - name: Build
run: cmake --build build --config Debug --target ci_module_cpp20 run: cmake --build build --config Debug --target ci_module_cpp20
+17 -1
View File
@@ -27,7 +27,6 @@
/docs/docset/JSON_for_Modern_C++.tgz /docs/docset/JSON_for_Modern_C++.tgz
/docs/docset/docSet.dsidx /docs/docset/docSet.dsidx
/docs/mkdocs/.cache/ /docs/mkdocs/.cache/
/docs/mkdocs/docs/__pycache__/
/docs/mkdocs/hooks/__pycache__/ /docs/mkdocs/hooks/__pycache__/
/docs/mkdocs/scripts/mermaid/node_modules/ /docs/mkdocs/scripts/mermaid/node_modules/
/docs/mkdocs/site/ /docs/mkdocs/site/
@@ -47,3 +46,20 @@ nlohmann_json.spdx
# Bazel-related # Bazel-related
MODULE.bazel.lock MODULE.bazel.lock
# backups left by `make check-amalgamation` or the ci_test_amalgamation target if they are interrupted
/BUILD.bazel~
/nlohmann_json.natvis~
/single_include/nlohmann/*.hpp~
/venv_astyle/
# release outputs of `make release`
/include.zip
/include.zip.asc
/json.tar.xz
/json.tar.xz.asc
/release_files/
/single_include/nlohmann/*.asc
# GCC module cache
/gcm.cache/
+26
View File
@@ -20,11 +20,13 @@ cc_library(
hdrs = [ hdrs = [
"include/nlohmann/adl_serializer.hpp", "include/nlohmann/adl_serializer.hpp",
"include/nlohmann/byte_container_with_subtype.hpp", "include/nlohmann/byte_container_with_subtype.hpp",
"include/nlohmann/detail/abi_config.hpp",
"include/nlohmann/detail/abi_macros.hpp", "include/nlohmann/detail/abi_macros.hpp",
"include/nlohmann/detail/bit_ops.hpp", "include/nlohmann/detail/bit_ops.hpp",
"include/nlohmann/detail/conversions/from_json.hpp", "include/nlohmann/detail/conversions/from_json.hpp",
"include/nlohmann/detail/conversions/to_chars.hpp", "include/nlohmann/detail/conversions/to_chars.hpp",
"include/nlohmann/detail/conversions/to_json.hpp", "include/nlohmann/detail/conversions/to_json.hpp",
"include/nlohmann/detail/conversions/zmij.hpp",
"include/nlohmann/detail/exceptions.hpp", "include/nlohmann/detail/exceptions.hpp",
"include/nlohmann/detail/hash.hpp", "include/nlohmann/detail/hash.hpp",
"include/nlohmann/detail/input/binary_reader.hpp", "include/nlohmann/detail/input/binary_reader.hpp",
@@ -65,9 +67,31 @@ cc_library(
"include/nlohmann/detail/string_escape.hpp", "include/nlohmann/detail/string_escape.hpp",
"include/nlohmann/detail/string_utils.hpp", "include/nlohmann/detail/string_utils.hpp",
"include/nlohmann/detail/value_t.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.hpp",
"include/nlohmann/json_fwd.hpp", "include/nlohmann/json_fwd.hpp",
"include/nlohmann/json_literals.hpp", "include/nlohmann/json_literals.hpp",
"include/nlohmann/json_view.hpp",
"include/nlohmann/ordered_map.hpp", "include/nlohmann/ordered_map.hpp",
"include/nlohmann/thirdparty/hedley/hedley.hpp", "include/nlohmann/thirdparty/hedley/hedley.hpp",
"include/nlohmann/thirdparty/hedley/hedley_undef.hpp", "include/nlohmann/thirdparty/hedley/hedley_undef.hpp",
@@ -81,6 +105,8 @@ cc_library(
hdrs = [ hdrs = [
"single_include/nlohmann/json.hpp", "single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp", "single_include/nlohmann/json_fwd.hpp",
"single_include/nlohmann/json_literals.hpp",
"single_include/nlohmann/json_view.hpp",
], ],
includes = ["single_include"], includes = ["single_include"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
+1 -1
View File
@@ -8,7 +8,7 @@ authors:
website: https://nlohmann.me website: https://nlohmann.me
title: "JSON for Modern C++" title: "JSON for Modern C++"
version: 3.12.0 version: 3.12.0
date-released: 2025-04-07 date-released: 2025-04-11
license: MIT license: MIT
repository-code: "https://github.com/nlohmann/json" repository-code: "https://github.com/nlohmann/json"
url: https://json.nlohmann.me url: https://json.nlohmann.me
+1 -1
View File
@@ -30,7 +30,7 @@ endif ()
option(NLOHMANN_JSON_BUILD_MODULES "Build C++ modules support" OFF) option(NLOHMANN_JSON_BUILD_MODULES "Build C++ modules support" OFF)
if(NLOHMANN_JSON_BUILD_MODULES) if(NLOHMANN_JSON_BUILD_MODULES)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28) if(NOT CMAKE_VERSION VERSION_LESS 3.28)
message(STATUS "Building nlohmann.json C++ module") message(STATUS "Building nlohmann.json C++ module")
add_subdirectory(src/modules) add_subdirectory(src/modules)
else() else()
+7 -4
View File
@@ -14,7 +14,7 @@ This file describes the source for supporting files; that is, files that are not
The [GitHub Actions](https://docs.github.com/en/actions) workflows that build, test, and analyze the library. Each file in this folder defines one workflow: The [GitHub Actions](https://docs.github.com/en/actions) workflows that build, test, and analyze the library. Each file in this folder defines one workflow:
- `ubuntu.yml`, `macos.yml`, `windows.yml` — build and run the test suite on Linux, macOS, and Windows. - `ubuntu.yml`, `macos.yml`, `windows.yml` — build and run the test suite on Linux, macOS, and Windows.
- `check_amalgamation.yml` — verify that the single-header amalgamation in `single_include` is up to date on pull requests. - `check_amalgamation.yml` — verify on pull requests and pushes to `develop` that the generated files (the single-header amalgamation in `single_include`, `BUILD.bazel`, and `nlohmann_json.natvis`) are up to date.
- `comment_check_amalgamation.yml` — comment on a pull request when the amalgamation check failed. - `comment_check_amalgamation.yml` — comment on a pull request when the amalgamation check failed.
- `cifuzz.yml` — run short fuzzing sessions via [OSS-Fuzz CIFuzz](https://google.github.io/oss-fuzz/getting-started/continuous-integration/) on pull requests. - `cifuzz.yml` — run short fuzzing sessions via [OSS-Fuzz CIFuzz](https://google.github.io/oss-fuzz/getting-started/continuous-integration/) on pull requests.
- `codeql-analysis.yml` — run [CodeQL](https://codeql.github.com) code scanning. - `codeql-analysis.yml` — run [CodeQL](https://codeql.github.com) code scanning.
@@ -24,7 +24,9 @@ The [GitHub Actions](https://docs.github.com/en/actions) workflows that build, t
- `dependency-review.yml` — scan dependency changes in pull requests for known vulnerabilities. - `dependency-review.yml` — scan dependency changes in pull requests for known vulnerabilities.
- `labeler.yml` — the "Pull Request Labeler" workflow (see `.github/labeler.yml`). - `labeler.yml` — the "Pull Request Labeler" workflow (see `.github/labeler.yml`).
- `stale.yml` — comment on and close stale issues and pull requests. - `stale.yml` — comment on and close stale issues and pull requests.
- `publish_documentation.yml` — build and publish the documentation on every merge to the `develop` branch. - `publish_documentation.yml` — build and publish the documentation on pushes to the `develop` branch that touch the documentation sources (or the files it embeds).
- `check_docs_links.yml` — check the links of the documentation weekly, as external links can break without any change in this repository.
- `cancel_closed_pr_runs.yml` — cancel unfinished workflow runs of a pull request once it is closed or merged.
Further documentation: Further documentation:
@@ -266,8 +268,9 @@ meson setup builddir
ninja -C builddir ninja -C builddir
``` ```
`meson_options.txt` defines the options, which mirror the CMake options that change the library's target (for example, `meson_options.txt` defines the options, which mirror the names of 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` `-DDiagnostics=true`); their defaults may differ (for example, `MultipleHeaders` defaults to `false` in Meson, while
`JSON_MultipleHeaders` is `ON` in CMake). 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 ([`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. stay in sync with the CMake options.
+1
View File
@@ -1,5 +1,6 @@
module( module(
name = "nlohmann_json", name = "nlohmann_json",
version = "3.12.0",
compatibility_level = 1, compatibility_level = 1,
) )
+49 -31
View File
@@ -1,4 +1,4 @@
.PHONY: pretty clean ChangeLog.md release update_hedley update_hedley_undef BUILD.bazel natvis macro_builder_check check_build_options .PHONY: all amalgamate check-amalgamation check_build_options pretty install_astyle clean ChangeLog.md release update_hedley update_hedley_undef BUILD.bazel natvis macro_builder_check run_benchmarks pvs_studio serve_header reuse spdx
########################################################################## ##########################################################################
# configuration # configuration
@@ -26,6 +26,7 @@ AMALGAMATED_FILE=single_include/nlohmann/json.hpp
AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
# json_literals.hpp only includes <nlohmann/json.hpp>, so it is copied verbatim # json_literals.hpp only includes <nlohmann/json.hpp>, so it is copied verbatim
AMALGAMATED_LITERALS_FILE=single_include/nlohmann/json_literals.hpp 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 # the header with the argument-counting macros generated by tools/macro_builder
MACRO_SCOPE_HPP=include/nlohmann/detail/macro_scope.hpp MACRO_SCOPE_HPP=include/nlohmann/detail/macro_scope.hpp
@@ -37,16 +38,22 @@ MACRO_SCOPE_HPP=include/nlohmann/detail/macro_scope.hpp
# main target # main target
all: 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 "BUILD.bazel - regenerate the Bazel BUILD file from the include/nlohmann sources"
@echo "ChangeLog.md - generate ChangeLog file" @echo "ChangeLog.md - generate ChangeLog file"
@echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date" @echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date"
@echo "check_build_options - check that the Meson build and the pkg-config files offer the options of the CMake target"
@echo "clean - remove built files" @echo "clean - remove built files"
@echo "fuzzing - see tests/fuzzing.md for how to build and run the fuzzers" @echo "(fuzzers) - see tests/fuzzing.md, or run 'make -C tests fuzzers' to build the AFL fuzzers"
@echo "macro_builder_check - check that macro_scope.hpp matches tools/macro_builder's output" @echo "macro_builder_check - check that macro_scope.hpp matches tools/macro_builder's output"
@echo "natvis - regenerate nlohmann_json.natvis from the current ABI tags and version" @echo "natvis - regenerate nlohmann_json.natvis from the current ABI tags and version"
@echo "pretty - beautify code with Artistic Style" @echo "pretty - beautify code with Artistic Style"
@echo "pvs_studio - run the PVS-Studio static analyzer and open the report"
@echo "release - create the release files (include.zip, json.tar.xz, single headers, signatures, hashes)"
@echo "reuse - annotate the source files with REUSE license headers and lint them"
@echo "run_benchmarks - build and run benchmarks" @echo "run_benchmarks - build and run benchmarks"
@echo "serve_header - serve the single header, re-amalgamated on demand (see tools/serve_header)"
@echo "spdx - generate the SPDX software bill of materials nlohmann_json.spdx"
@echo "update_hedley - download Hedley and regenerate hedley.hpp / hedley_undef.hpp" @echo "update_hedley - download Hedley and regenerate hedley.hpp / hedley_undef.hpp"
@echo "update_hedley_undef - rebuild hedley_undef.hpp from the JSON_HEDLEY_* #define names in hedley.hpp" @echo "update_hedley_undef - rebuild hedley_undef.hpp from the JSON_HEDLEY_* #define names in hedley.hpp"
@@ -90,10 +97,10 @@ install_astyle:
# call the Artistic Style pretty printer on all source files # call the Artistic Style pretty printer on all source files
pretty: install_astyle 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 # 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 $(MAKE) pretty
# call the amalgamation tool for json.hpp # call the amalgamation tool for json.hpp
@@ -108,13 +115,22 @@ $(AMALGAMATED_FWD_FILE): $(SRCS)
$(AMALGAMATED_LITERALS_FILE): include/nlohmann/json_literals.hpp $(AMALGAMATED_LITERALS_FILE): include/nlohmann/json_literals.hpp
cp include/nlohmann/json_literals.hpp $(AMALGAMATED_LITERALS_FILE) cp include/nlohmann/json_literals.hpp $(AMALGAMATED_LITERALS_FILE)
# call the amalgamation tool for json_view.hpp (keeps including json.hpp)
$(AMALGAMATED_VIEW_FILE): $(SRCS)
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_view.json -s . --verbose=yes
NATVIS_VENV=tools/generate_natvis/venv
# regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp # regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp
# (the dependencies are installed into a virtual environment first)
natvis: natvis:
python3 tools/generate_natvis/generate_natvis.py . @test -d $(NATVIS_VENV) || python3 -mvenv $(NATVIS_VENV)
@$(NATVIS_VENV)/bin/python3 -c 'import jinja2' 2>/dev/null || $(NATVIS_VENV)/bin/pip3 install --quiet -r tools/generate_natvis/requirements.txt
$(NATVIS_VENV)/bin/python3 tools/generate_natvis/generate_natvis.py .
# regenerate the two tools/macro_builder blocks of $(MACRO_SCOPE_HPP) (see its README.md) and diff against the # regenerate the two tools/macro_builder blocks of $(MACRO_SCOPE_HPP) (see its README.md) and diff against the
# checked-in header; phony, because it never writes $(MACRO_SCOPE_HPP) itself # checked-in header; phony, because it never writes $(MACRO_SCOPE_HPP) itself
macro_builder_check: macro_builder_check: install_astyle
@set -e; \ @set -e; \
TMPDIR=$$(mktemp -d ./macro_builder_check.XXXXXX); \ TMPDIR=$$(mktemp -d ./macro_builder_check.XXXXXX); \
trap 'rm -rf "$$TMPDIR"' EXIT; \ trap 'rm -rf "$$TMPDIR"' EXIT; \
@@ -131,27 +147,27 @@ macro_builder_check:
check_build_options: check_build_options:
python3 tools/check_build_options/check_build_options.py . 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 if the single headers have been amalgamated from the nlohmann sources and if BUILD.bazel and
# nlohmann_json.natvis are up to date; all checks are run, and the checked-in files are always restored
check-amalgamation: check-amalgamation:
@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ @status=0; \
@mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ banner() { printf '===================================================================\n %s\n===================================================================\n' "$$1"; }; \
@mv $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~ for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE) BUILD.bazel nlohmann_json.natvis; do \
@$(MAKE) amalgamate mv "$$FILE" "$$FILE~" || exit 1; \
@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) done; \
@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) $(MAKE) amalgamate || status=1; \
@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) $(MAKE) BUILD.bazel || status=1; \
@mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) $(MAKE) natvis || status=1; \
@mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE); do \
@mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE) diff "$$FILE" "$$FILE~" || { banner "$$FILE is out of date! Amalgamation required! Please read the contribution guidelines in file .github/CONTRIBUTING.md."; status=1; }; \
@mv BUILD.bazel BUILD.bazel~ done; \
@$(MAKE) BUILD.bazel diff BUILD.bazel BUILD.bazel~ || { banner "BUILD.bazel is out of date! Please run 'make BUILD.bazel'."; status=1; }; \
@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) diff nlohmann_json.natvis nlohmann_json.natvis~ || { banner "nlohmann_json.natvis is out of date! Please run 'make natvis'."; status=1; }; \
@mv BUILD.bazel~ BUILD.bazel for FILE in $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_VIEW_FILE) BUILD.bazel nlohmann_json.natvis; do \
@mv nlohmann_json.natvis nlohmann_json.natvis~ mv "$$FILE~" "$$FILE"; \
@$(MAKE) natvis done; \
@diff nlohmann_json.natvis nlohmann_json.natvis~ || (echo "===================================================================\n nlohmann_json.natvis is out of date! Please run 'make natvis'.\n===================================================================" ; mv nlohmann_json.natvis~ nlohmann_json.natvis ; false) $(MAKE) macro_builder_check || status=1; \
@mv nlohmann_json.natvis~ nlohmann_json.natvis exit $$status
@$(MAKE) macro_builder_check
# generate the Bazel BUILD file; phony, because a removed header would not trigger a rebuild # generate the Bazel BUILD file; phony, because a removed header would not trigger a rebuild
BUILD.bazel: BUILD.bazel:
@@ -188,7 +204,7 @@ json.tar.xz:
# We use `-X` to make the resulting ZIP file reproducible, see # We use `-X` to make the resulting ZIP file reproducible, see
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>. # <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
include.zip: BUILD.bazel 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 meson_options.txt 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. # Create the files for a release and add signatures and hashes.
release: include.zip json.tar.xz release: include.zip json.tar.xz
@@ -198,11 +214,13 @@ release: include.zip json.tar.xz
gpg --armor --detach-sig $(AMALGAMATED_FILE) gpg --armor --detach-sig $(AMALGAMATED_FILE)
gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE) gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE)
gpg --armor --detach-sig $(AMALGAMATED_LITERALS_FILE) gpg --armor --detach-sig $(AMALGAMATED_LITERALS_FILE)
gpg --armor --detach-sig $(AMALGAMATED_VIEW_FILE)
gpg --armor --detach-sig json.tar.xz gpg --armor --detach-sig json.tar.xz
cp $(AMALGAMATED_FILE) release_files cp $(AMALGAMATED_FILE) release_files
cp $(AMALGAMATED_FWD_FILE) release_files cp $(AMALGAMATED_FWD_FILE) release_files
cp $(AMALGAMATED_LITERALS_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 cd release_files ; shasum -a 256 $$(find . -type f -not -name '*.asc' | sed 's|^\./||' | sort) > hashes.txt
@@ -212,8 +230,8 @@ release: include.zip json.tar.xz
# clean up # clean up
clean: clean:
rm -fr fuzz fuzz-testing *.dSYM tests/*.dSYM rm -fr *.dSYM tests/*.dSYM tests/parse_*_fuzzer
rm -fr cmake-build-benchmarks fuzz-testing cmake-build-pvs-studio release_files rm -fr cmake-build-benchmarks cmake-build-pvs-studio release_files
$(MAKE) clean -Cdocs $(MAKE) clean -Cdocs
+436 -447
View File
@@ -48,6 +48,7 @@
- [Pkg-config](#pkg-config) - [Pkg-config](#pkg-config)
- [License](#license) - [License](#license)
- [Contact](#contact) - [Contact](#contact)
- [Security](#security)
- [Thanks](#thanks) - [Thanks](#thanks)
- [Used third-party tools](#used-third-party-tools) - [Used third-party tools](#used-third-party-tools)
- [Notes](#notes) - [Notes](#notes)
@@ -112,9 +113,9 @@ There is also a [**docset**](https://github.com/Kapeli/Dash-User-Contributions/t
## Quick reference ## Quick reference
- **Constructors** [basic_json](https://json.nlohmann.me/api/basic_json/basic_json), [array](https://json.nlohmann.me/api/basic_json/array), [binary](https://json.nlohmann.me/api/basic_json/binary), [object](https://json.nlohmann.me/api/basic_json/object) - **Constructors**: [basic_json](https://json.nlohmann.me/api/basic_json/basic_json), [array](https://json.nlohmann.me/api/basic_json/array), [binary](https://json.nlohmann.me/api/basic_json/binary), [object](https://json.nlohmann.me/api/basic_json/object)
- **Object inspection**: [type](https://json.nlohmann.me/api/basic_json/type), [operator value_t](https://json.nlohmann.me/api/basic_json/operator_value_t), [type_name](https://json.nlohmann.me/api/basic_json/type_name), [is_primitive](https://json.nlohmann.me/api/basic_json/is_primitive), [is_structured](https://json.nlohmann.me/api/basic_json/is_structured), [is_null](https://json.nlohmann.me/api/basic_json/is_null), [is_boolean](https://json.nlohmann.me/api/basic_json/is_boolean), [is_number](https://json.nlohmann.me/api/basic_json/is_number), [is_number_integer](https://json.nlohmann.me/api/basic_json/is_number_integer), [is_number_unsigned](https://json.nlohmann.me/api/basic_json/is_number_unsigned), [is_number_float](https://json.nlohmann.me/api/basic_json/is_number_float), [is_object](https://json.nlohmann.me/api/basic_json/is_object), [is_array](https://json.nlohmann.me/api/basic_json/is_array), [is_string](https://json.nlohmann.me/api/basic_json/is_string), [is_binary](https://json.nlohmann.me/api/basic_json/is_binary), [is_discarded](https://json.nlohmann.me/api/basic_json/is_discarded) - **Object inspection**: [type](https://json.nlohmann.me/api/basic_json/type), [operator value_t](https://json.nlohmann.me/api/basic_json/operator_value_t), [type_name](https://json.nlohmann.me/api/basic_json/type_name), [is_primitive](https://json.nlohmann.me/api/basic_json/is_primitive), [is_structured](https://json.nlohmann.me/api/basic_json/is_structured), [is_null](https://json.nlohmann.me/api/basic_json/is_null), [is_boolean](https://json.nlohmann.me/api/basic_json/is_boolean), [is_number](https://json.nlohmann.me/api/basic_json/is_number), [is_number_integer](https://json.nlohmann.me/api/basic_json/is_number_integer), [is_number_unsigned](https://json.nlohmann.me/api/basic_json/is_number_unsigned), [is_number_float](https://json.nlohmann.me/api/basic_json/is_number_float), [is_object](https://json.nlohmann.me/api/basic_json/is_object), [is_array](https://json.nlohmann.me/api/basic_json/is_array), [is_string](https://json.nlohmann.me/api/basic_json/is_string), [is_binary](https://json.nlohmann.me/api/basic_json/is_binary), [is_discarded](https://json.nlohmann.me/api/basic_json/is_discarded)
- **Value access**; [get](https://json.nlohmann.me/api/basic_json/get), [get_to](https://json.nlohmann.me/api/basic_json/get_to), [get_ptr](https://json.nlohmann.me/api/basic_json/get_ptr), [get_ref](https://json.nlohmann.me/api/basic_json/get_ref), [operator ValueType](https://json.nlohmann.me/api/basic_json/operator_ValueType), [get_binary](https://json.nlohmann.me/api/basic_json/get_binary) - **Value access**: [get](https://json.nlohmann.me/api/basic_json/get), [get_to](https://json.nlohmann.me/api/basic_json/get_to), [get_ptr](https://json.nlohmann.me/api/basic_json/get_ptr), [get_ref](https://json.nlohmann.me/api/basic_json/get_ref), [operator ValueType](https://json.nlohmann.me/api/basic_json/operator_ValueType), [get_binary](https://json.nlohmann.me/api/basic_json/get_binary)
- **Element access**: [at](https://json.nlohmann.me/api/basic_json/at), [operator[]](https://json.nlohmann.me/api/basic_json/operator[]), [value](https://json.nlohmann.me/api/basic_json/value), [front](https://json.nlohmann.me/api/basic_json/front), [back](https://json.nlohmann.me/api/basic_json/back) - **Element access**: [at](https://json.nlohmann.me/api/basic_json/at), [operator[]](https://json.nlohmann.me/api/basic_json/operator[]), [value](https://json.nlohmann.me/api/basic_json/value), [front](https://json.nlohmann.me/api/basic_json/front), [back](https://json.nlohmann.me/api/basic_json/back)
- **Lookup**: [find](https://json.nlohmann.me/api/basic_json/find), [count](https://json.nlohmann.me/api/basic_json/count), [contains](https://json.nlohmann.me/api/basic_json/contains) - **Lookup**: [find](https://json.nlohmann.me/api/basic_json/find), [count](https://json.nlohmann.me/api/basic_json/count), [contains](https://json.nlohmann.me/api/basic_json/contains)
- **Iterators**: [begin](https://json.nlohmann.me/api/basic_json/begin), [cbegin](https://json.nlohmann.me/api/basic_json/cbegin), [end](https://json.nlohmann.me/api/basic_json/end), [cend](https://json.nlohmann.me/api/basic_json/cend), [rbegin](https://json.nlohmann.me/api/basic_json/rbegin), [rend](https://json.nlohmann.me/api/basic_json/rend), [crbegin](https://json.nlohmann.me/api/basic_json/crbegin), [crend](https://json.nlohmann.me/api/basic_json/crend), [items](https://json.nlohmann.me/api/basic_json/items) - **Iterators**: [begin](https://json.nlohmann.me/api/basic_json/begin), [cbegin](https://json.nlohmann.me/api/basic_json/cbegin), [end](https://json.nlohmann.me/api/basic_json/end), [cend](https://json.nlohmann.me/api/basic_json/cend), [rbegin](https://json.nlohmann.me/api/basic_json/rbegin), [rend](https://json.nlohmann.me/api/basic_json/rend), [crbegin](https://json.nlohmann.me/api/basic_json/crbegin), [crend](https://json.nlohmann.me/api/basic_json/crend), [items](https://json.nlohmann.me/api/basic_json/items)
@@ -1184,9 +1185,17 @@ binary[1]; // 0xFE
binary.set_subtype(0x10); binary.set_subtype(0x10);
// serialize to MessagePack // serialize to MessagePack
auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE auto msgpack = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE
``` ```
### Zero-copy views
Header `<nlohmann/json_view.hpp>` adds `json_document`/`json_view`, a read-only, non-owning way to look at a parsed
JSON text: parsing builds a flat index (16 bytes per value) instead of a tree, strings and numbers stay in the source
text, and `materialize()` builds a `json` value for a subtree only when you actually need one. See
[Zero-copy JSON views](https://json.nlohmann.me/features/json_view/) for the details, including which inputs are
borrowed and which are copied.
## Customers ## 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). 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).
@@ -1220,17 +1229,7 @@ I would be happy to learn about other compilers/versions.
Please note: Please note:
- GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler. - GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler.
- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. - For GCC running on MinGW or Android, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`) may occur. Note this is not an issue with the code, but rather with the compiler or C++ standard library itself: use a recent toolchain (for Android, a current [NDK](https://developer.android.com/ndk) with the LLVM C++ library `APP_STL := c++_shared`, and for MinGW, a distribution with a complete C++11 standard library). See [this discussion](https://github.com/nlohmann/json/issues/136) for MinGW and [this discussion](https://github.com/nlohmann/json/issues/219) for the old Android NDK using `APP_STL := gnustl_static`.
```makefile
APP_STL := c++_shared
NDK_TOOLCHAIN_VERSION := clang3.6
APP_CPPFLAGS += -frtti -fexceptions
```
The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10.
- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`) may occur. Note this is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](https://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).
- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case. - Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case.
@@ -1394,9 +1393,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 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 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, including the conversion of the digits to text by Xiang JunBo and the SIMD instruction sequence of Dougall Johnson, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright &copy; 2025 [Victor Zverovich](https://github.com/vitaut)
- The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/). - The class contains 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 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"> <img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
@@ -1437,436 +1439,416 @@ I deeply appreciate the help of the following people.
12. [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual Studio. 12. [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual Studio.
13. [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types. 13. [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types.
14. [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling. 14. [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling.
15. [dariomt](https://github.com/dariomt) fixed some typos in the examples. 15. [dariomt](https://github.com/dariomt) fixed some typos in the examples and fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values.
16. [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation. 16. [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation.
17. [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue. 17. [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue.
18. [Huu Nguyen](https://github.com/whoshuu) corrected a variable name in the documentation. 18. [Huu Nguyen](https://github.com/whoshuu) corrected a variable name in the documentation.
19. [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference. 19. [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference.
20. [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values. 20. [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK.
21. [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK. 21. [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio.
22. [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio. 22. [406345](https://github.com/406345) fixed two small warnings.
23. [406345](https://github.com/406345) fixed two small warnings. 23. [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function.
24. [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function. 24. [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines.
25. [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines. 25. [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers.
26. [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers. 26. [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file.
27. [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file. 27. [msm-](https://github.com/msm-) added support for American Fuzzy Lop.
28. [msm-](https://github.com/msm-) added support for American Fuzzy Lop. 28. [Annihil](https://github.com/Annihil) fixed an example in the README file.
29. [Annihil](https://github.com/Annihil) fixed an example in the README file. 29. [Themercee](https://github.com/Themercee) noted a wrong URL in the README file.
30. [Themercee](https://github.com/Themercee) noted a wrong URL in the README file. 30. [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`.
31. [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`. 31. [abc100m](https://github.com/abc100m) analyzed the issues with GCC 4.8 and proposed a [partial solution](https://github.com/nlohmann/json/pull/212).
32. [abc100m](https://github.com/abc100m) analyzed the issues with GCC 4.8 and proposed a [partial solution](https://github.com/nlohmann/json/pull/212). 32. [zewt](https://github.com/zewt) added useful notes to the README file about Android.
33. [zewt](https://github.com/zewt) added useful notes to the README file about Android. 33. [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake.
34. [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake. 34. [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files.
35. [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files. 35. [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal).
36. [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal). 36. [Mário Feroldi](https://github.com/thelostt) fixed a small typo.
37. [Mário Feroldi](https://github.com/thelostt) fixed a small typo. 37. [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release.
38. [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release. 38. [Damien](https://github.com/dtoma) fixed one of the last conversion warnings.
39. [Damien](https://github.com/dtoma) fixed one of the last conversion warnings. 39. [Thomas Braun](https://github.com/t-b) fixed a warning in a test case and adjusted MSVC calls in the CI.
40. [Thomas Braun](https://github.com/t-b) fixed a warning in a test case and adjusted MSVC calls in the CI. 40. [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks.
41. [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks. 41. [Stefan](https://github.com/5tefan) fixed a minor issue in the documentation.
42. [Stefan](https://github.com/5tefan) fixed a minor issue in the documentation. 42. [Vasil Dimov](https://github.com/vasild) fixed the documentation regarding conversions from `std::multiset`.
43. [Vasil Dimov](https://github.com/vasild) fixed the documentation regarding conversions from `std::multiset`. 43. [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion.
44. [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion. 44. [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix.
45. [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix. 45. [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file.
46. [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file. 46. [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function.
47. [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function. 47. [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing.
48. [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing. 48. [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan.
49. [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan. 49. [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning and supported the implementation of user-defined types.
50. [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning. 50. [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check.
51. [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check. 51. [Bosswestfalen](https://github.com/Bosswestfalen) merged two iterator classes into a smaller one.
52. [Bosswestfalen](https://github.com/Bosswestfalen) merged two iterator classes into a smaller one. 52. [Daniel599](https://github.com/Daniel599) helped to get Travis to execute the tests with Clang's sanitizers and allowed to use more algorithms with the `items()` function.
53. [Daniel599](https://github.com/Daniel599) helped to get Travis to execute the tests with Clang's sanitizers. 53. [Jonathan Lee](https://github.com/vjon) fixed an example in the README file.
54. [Jonathan Lee](https://github.com/vjon) fixed an example in the README file. 54. [gnzlbg](https://github.com/gnzlbg) supported the implementation of user-defined types.
55. [gnzlbg](https://github.com/gnzlbg) supported the implementation of user-defined types. 55. [Alexej Harm](https://github.com/qis) helped to get the user-defined types working with Visual Studio.
56. [Alexej Harm](https://github.com/qis) helped to get the user-defined types working with Visual Studio. 56. [EnricoBilla](https://github.com/EnricoBilla) noted a typo in an example.
57. [Jared Grubb](https://github.com/jaredgrubb) supported the implementation of user-defined types. 57. [Martin Hořeňovský](https://github.com/horenmar) found a way for a 2x speedup for the compilation time of the test suite.
58. [EnricoBilla](https://github.com/EnricoBilla) noted a typo in an example. 58. [ukhegg](https://github.com/ukhegg) proposed an improvement for the examples section.
59. [Martin Hořeňovský](https://github.com/horenmar) found a way for a 2x speedup for the compilation time of the test suite. 59. [rswanson-ihi](https://github.com/rswanson-ihi) noted a typo in the README.
60. [ukhegg](https://github.com/ukhegg) proposed an improvement for the examples section. 60. [Mihai Stan](https://github.com/stanmihai4) fixed a bug in the comparison with `nullptr`s.
61. [rswanson-ihi](https://github.com/rswanson-ihi) noted a typo in the README. 61. [Tushar Maheshwari](https://github.com/tusharpm) added [cotire](https://github.com/sakra/cotire) support to speed up the compilation.
62. [Mihai Stan](https://github.com/stanmihai4) fixed a bug in the comparison with `nullptr`s. 62. [TedLyngmo](https://github.com/TedLyngmo) noted a typo in the README, removed unnecessary bit arithmetic, and fixed some `-Weffc++` warnings.
63. [Tushar Maheshwari](https://github.com/tusharpm) added [cotire](https://github.com/sakra/cotire) support to speed up the compilation. 63. [Krzysztof Woś](https://github.com/krzysztofwos) made exceptions more visible.
64. [TedLyngmo](https://github.com/TedLyngmo) noted a typo in the README, removed unnecessary bit arithmetic, and fixed some `-Weffc++` warnings. 64. [ftillier](https://github.com/ftillier) fixed a compiler warning.
65. [Krzysztof Woś](https://github.com/krzysztofwos) made exceptions more visible. 65. [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped.
66. [ftillier](https://github.com/ftillier) fixed a compiler warning. 66. [Fytch](https://github.com/Fytch) found a bug in the documentation.
67. [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped. 67. [Jay Sistar](https://github.com/Type1J) implemented a Meson build description.
68. [Fytch](https://github.com/Fytch) found a bug in the documentation. 68. [Henry Lee](https://github.com/HenryRLee) fixed a warning in ICC and improved the iterator implementation.
69. [Jay Sistar](https://github.com/Type1J) implemented a Meson build description. 69. [Vincent Thiery](https://github.com/vthiery) maintains a package for the Conan package manager.
70. [Henry Lee](https://github.com/HenryRLee) fixed a warning in ICC and improved the iterator implementation. 70. [Steffen](https://github.com/koemeet) fixed a potential issue with MSVC and `std::min`.
71. [Vincent Thiery](https://github.com/vthiery) maintains a package for the Conan package manager. 71. [Mike Tzou](https://github.com/Chocobo1) fixed some typos.
72. [Steffen](https://github.com/koemeet) fixed a potential issue with MSVC and `std::min`. 72. [amrcode](https://github.com/amrcode) noted misleading documentation about comparison of floats.
73. [Mike Tzou](https://github.com/Chocobo1) fixed some typos. 73. [Oleg Endo](https://github.com/olegendo) reduced the memory consumption by replacing `<iostream>` with `<iosfwd>`.
74. [amrcode](https://github.com/amrcode) noted misleading documentation about comparison of floats. 74. [dan-42](https://github.com/dan-42) cleaned up the CMake files to simplify including/reusing of the library.
75. [Oleg Endo](https://github.com/olegendo) reduced the memory consumption by replacing `<iostream>` with `<iosfwd>`. 75. [Nikita Ofitserov](https://github.com/himikof) allowed for moving values from initializer lists.
76. [dan-42](https://github.com/dan-42) cleaned up the CMake files to simplify including/reusing of the library. 76. [Greg Hurrell](https://github.com/wincent) fixed a typo.
77. [Nikita Ofitserov](https://github.com/himikof) allowed for moving values from initializer lists. 77. [Dmitry Kukovinets](https://github.com/DmitryKuk) fixed a typo.
78. [Greg Hurrell](https://github.com/wincent) fixed a typo. 78. [kbthomp1](https://github.com/kbthomp1) fixed an issue related to the Intel OSX compiler.
79. [Dmitry Kukovinets](https://github.com/DmitryKuk) fixed a typo. 79. [Markus Werle](https://github.com/daixtrose) fixed a typo.
80. [kbthomp1](https://github.com/kbthomp1) fixed an issue related to the Intel OSX compiler. 80. [WebProdPP](https://github.com/WebProdPP) fixed a subtle error in a precondition check.
81. [Markus Werle](https://github.com/daixtrose) fixed a typo. 81. [Alex](https://github.com/leha-bot) noted an error in a code sample.
82. [WebProdPP](https://github.com/WebProdPP) fixed a subtle error in a precondition check. 82. [Tom de Geus](https://github.com/tdegeus) reported some warnings with ICC and helped to fix them.
83. [Alex](https://github.com/leha-bot) noted an error in a code sample. 83. [Perry Kundert](https://github.com/pjkundert) simplified reading from input streams.
84. [Tom de Geus](https://github.com/tdegeus) reported some warnings with ICC and helped to fix them. 84. [Sonu Lohani](https://github.com/sonulohani) fixed a small compilation error, fixed the compilation with MSVC 2015 in debug mode and fixed a warning.
85. [Perry Kundert](https://github.com/pjkundert) simplified reading from input streams. 85. [Jamie Seward](https://github.com/jseward) fixed all MSVC warnings and avoided unnecessary string copies in `find()` and `count()`.
86. [Sonu Lohani](https://github.com/sonulohani) fixed a small compilation error. 86. [Nate Vargas](https://github.com/eld00d) added a Doxygen tag file.
87. [Jamie Seward](https://github.com/jseward) fixed all MSVC warnings. 87. [pvleuven](https://github.com/pvleuven) helped to fix a warning in ICC.
88. [Nate Vargas](https://github.com/eld00d) added a Doxygen tag file. 88. [Pavel](https://github.com/crea7or) helped to fix some warnings in MSVC.
89. [pvleuven](https://github.com/pvleuven) helped to fix a warning in ICC. 89. [Mitja](https://github.com/Itja) fixed some typos.
90. [Pavel](https://github.com/crea7or) helped to fix some warnings in MSVC. 90. [Jorrit Wronski](https://github.com/jowr) updated the Hunter package links.
91. [Jamie Seward](https://github.com/jseward) avoided unnecessary string copies in `find()` and `count()`. 91. [Matthias Möller](https://github.com/TinyTinni) added a `.natvis` for the MSVC debug view and removed the dependency from `std::stringstream`.
92. [Mitja](https://github.com/Itja) fixed some typos. 92. [bogemic](https://github.com/bogemic) fixed some C++17 deprecation warnings.
93. [Jorrit Wronski](https://github.com/jowr) updated the Hunter package links. 93. [Eren Okka](https://github.com/erengy) fixed some MSVC warnings.
94. [Matthias Möller](https://github.com/TinyTinni) added a `.natvis` for the MSVC debug view. 94. [abolz](https://github.com/abolz) integrated the Grisu2 algorithm for proper floating-point formatting, allowing more roundtrip checks to succeed.
95. [bogemic](https://github.com/bogemic) fixed some C++17 deprecation warnings. 95. [Vadim Evard](https://github.com/Pipeliner) fixed a Markdown issue in the README.
96. [Eren Okka](https://github.com/erengy) fixed some MSVC warnings. 96. [zerodefect](https://github.com/zerodefect) fixed a compiler warning.
97. [abolz](https://github.com/abolz) integrated the Grisu2 algorithm for proper floating-point formatting, allowing more roundtrip checks to succeed. 97. [Kert](https://github.com/kaidokert) allowed to template the string type in the serialization and added the possibility to override the exceptional behavior.
98. [Vadim Evard](https://github.com/Pipeliner) fixed a Markdown issue in the README. 98. [mark-99](https://github.com/mark-99) helped fix an ICC error.
99. [zerodefect](https://github.com/zerodefect) fixed a compiler warning. 99. [Patrik Huber](https://github.com/patrikhuber) fixed links in the README file.
100. [Kert](https://github.com/kaidokert) allowed to template the string type in the serialization and added the possibility to override the exceptional behavior. 100. [johnfb](https://github.com/johnfb) found a bug in the implementation of CBOR's indefinite length strings.
101. [mark-99](https://github.com/mark-99) helped fix an ICC error. 101. [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager.
102. [Patrik Huber](https://github.com/patrikhuber) fixed links in the README file. 102. [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise.
103. [johnfb](https://github.com/johnfb) found a bug in the implementation of CBOR's indefinite length strings. 103. [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback.
104. [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager. 104. [agrianius](https://github.com/agrianius) allowed dumping JSON to an alternative string type and added code to use alternative string implementations.
105. [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise. 105. [Kevin Tonon](https://github.com/ktonon) overworked the C++11 compiler checks in CMake.
106. [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback. 106. [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io).
107. [agrianius](https://github.com/agrianius) allowed dumping JSON to an alternative string type. 107. [Carlos O'Ryan](https://github.com/coryan) fixed a typo.
108. [Kevin Tonon](https://github.com/ktonon) overworked the C++11 compiler checks in CMake. 108. [James Upjohn](https://github.com/jupjohn) fixed a version number in the compilers section.
109. [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io). 109. [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration.
110. [Carlos O'Ryan](https://github.com/coryan) fixed a typo. 110. [Jan Schöppach](https://github.com/dns13) fixed a typo.
111. [James Upjohn](https://github.com/jupjohn) fixed a version number in the compilers section. 111. [martin-mfg](https://github.com/martin-mfg) fixed a typo.
112. [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration. 112. [Julius Rakow](https://github.com/juliusrakow) fixed the Meson include directory and fixed the links to [cppreference.com](https://cppreference.com).
113. [Jan Schöppach](https://github.com/dns13) fixed a typo. 113. [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases.
114. [martin-mfg](https://github.com/martin-mfg) fixed a typo. 114. [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library and fixed an issue with a double macro definition.
115. [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`. 115. [thyu](https://github.com/thyu) fixed a compiler warning.
116. [agrianius](https://github.com/agrianius) added code to use alternative string implementations. 116. [David Guthrie](https://github.com/LEgregius) fixed a subtle compilation error with Clang 3.4.2.
117. [Daniel599](https://github.com/Daniel599) allowed to use more algorithms with the `items()` function. 117. [Dennis Fischer](https://github.com/dennisfischer) allowed to call `find_package` without installing the library.
118. [Julius Rakow](https://github.com/juliusrakow) fixed the Meson include directory and fixed the links to [cppreference.com](https://cppreference.com). 118. [Ben Berman](https://github.com/rivertam) made some error messages more understandable.
119. [Sonu Lohani](https://github.com/sonulohani) fixed the compilation with MSVC 2015 in debug mode. 119. [zakalibit](https://github.com/zakalibit) fixed a compilation problem with the Intel C++ compiler.
120. [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases. 120. [mandreyel](https://github.com/mandreyel) fixed a compilation problem.
121. [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library. 121. [Kostiantyn Ponomarenko](https://github.com/koponomarenko) added version and license information to the Meson build file.
122. [thyu](https://github.com/thyu) fixed a compiler warning. 122. [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8.
123. [David Guthrie](https://github.com/LEgregius) fixed a subtle compilation error with Clang 3.4.2. 123. [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory.
124. [Dennis Fischer](https://github.com/dennisfischer) allowed to call `find_package` without installing the library. 124. [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning.
125. [Hyeon Kim](https://github.com/simnalamburt) fixed an issue with a double macro definition. 125. [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define an enum/JSON mapping.
126. [Ben Berman](https://github.com/rivertam) made some error messages more understandable. 126. [efp](https://github.com/efp) added line and column information to parse errors.
127. [zakalibit](https://github.com/zakalibit) fixed a compilation problem with the Intel C++ compiler. 127. [julian-becker](https://github.com/julian-becker) added BSON support.
128. [mandreyel](https://github.com/mandreyel) fixed a compilation problem. 128. [Pratik Chowdhury](https://github.com/pratikpc) added support for structured bindings.
129. [Kostiantyn Ponomarenko](https://github.com/koponomarenko) added version and license information to the Meson build file. 129. [David Avedissian](https://github.com/davedissian) added support for Clang 5.0.1 (PS4 version).
130. [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8. 130. [Jonathan Dumaresq](https://github.com/dumarjo) implemented an input adapter to read from `FILE*`.
131. [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory. 131. [kjpus](https://github.com/kjpus) fixed a link in the documentation.
132. [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning. 132. [Manvendra Singh](https://github.com/manu-chroma) fixed a typo in the documentation.
133. [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define an enum/JSON mapping. 133. [ziggurat29](https://github.com/ziggurat29) fixed an MSVC warning.
134. [efp](https://github.com/efp) added line and column information to parse errors. 134. [Sylvain Corlay](https://github.com/SylvainCorlay) added code to avoid an issue with MSVC.
135. [julian-becker](https://github.com/julian-becker) added BSON support. 135. [mefyl](https://github.com/mefyl) fixed a bug when JSON was parsed from an input stream.
136. [Pratik Chowdhury](https://github.com/pratikpc) added support for structured bindings. 136. [Millian Poquet](https://github.com/mpoquet) allowed to install the library via Meson.
137. [David Avedissian](https://github.com/davedissian) added support for Clang 5.0.1 (PS4 version). 137. [Michael Behrns-Miller](https://github.com/moodboom) found an issue with a missing namespace.
138. [Jonathan Dumaresq](https://github.com/dumarjo) implemented an input adapter to read from `FILE*`. 138. [Nasztanovics Ferenc](https://github.com/naszta) fixed a compilation issue with libc 2.12.
139. [kjpus](https://github.com/kjpus) fixed a link in the documentation. 139. [Andreas Schwab](https://github.com/andreas-schwab) fixed the endian conversion.
140. [Manvendra Singh](https://github.com/manu-chroma) fixed a typo in the documentation. 140. [Mark-Dunning](https://github.com/Mark-Dunning) fixed a warning in MSVC.
141. [ziggurat29](https://github.com/ziggurat29) fixed an MSVC warning. 141. [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) added `operator/` for JSON Pointers and fixed a compilation issue with MSVC.
142. [Sylvain Corlay](https://github.com/SylvainCorlay) added code to avoid an issue with MSVC. 142. [John-Mark](https://github.com/johnmarkwayve) noted a missing header.
143. [mefyl](https://github.com/mefyl) fixed a bug when JSON was parsed from an input stream. 143. [Vitaly Zaitsev](https://github.com/xvitaly) fixed compilation with GCC 9.0.
144. [Millian Poquet](https://github.com/mpoquet) allowed to install the library via Meson. 144. [Laurent Stacul](https://github.com/stac47) fixed compilation with GCC 9.0.
145. [Michael Behrns-Miller](https://github.com/moodboom) found an issue with a missing namespace. 145. [Ivor Wanders](https://github.com/iwanders) helped to reduce the CMake requirement to version 3.1 and fixed the examples to catch exception by `const&`.
146. [Nasztanovics Ferenc](https://github.com/naszta) fixed a compilation issue with libc 2.12. 146. [njlr](https://github.com/njlr) updated the Buckaroo instructions.
147. [Andreas Schwab](https://github.com/andreas-schwab) fixed the endian conversion. 147. [Lion](https://github.com/lieff) fixed a compilation issue with GCC 7 on CentOS.
148. [Mark-Dunning](https://github.com/Mark-Dunning) fixed a warning in MSVC. 148. [Isaac Nickaein](https://github.com/nickaein) improved the integer serialization performance and implemented the `contains()` function.
149. [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) added `operator/` for JSON Pointers. 149. [past-due](https://github.com/past-due) suppressed an unfixable warning.
150. [John-Mark](https://github.com/johnmarkwayve) noted a missing header. 150. [Elvis Oric](https://github.com/elvisoric) improved Meson support.
151. [Vitaly Zaitsev](https://github.com/xvitaly) fixed compilation with GCC 9.0. 151. [Matěj Plch](https://github.com/Afforix) fixed an example in the README.
152. [Laurent Stacul](https://github.com/stac47) fixed compilation with GCC 9.0. 152. [Mark Beckwith](https://github.com/wythe) fixed two typos.
153. [Ivor Wanders](https://github.com/iwanders) helped to reduce the CMake requirement to version 3.1. 153. [scinart](https://github.com/scinart) fixed a bug in the serializer.
154. [njlr](https://github.com/njlr) updated the Buckaroo instructions. 154. [Patrick Boettcher](https://github.com/pboettch) implemented `push_back()` and `pop_back()` for JSON Pointers.
155. [Lion](https://github.com/lieff) fixed a compilation issue with GCC 7 on CentOS. 155. [Bruno Oliveira](https://github.com/nicoddemus) added support for Conda.
156. [Isaac Nickaein](https://github.com/nickaein) improved the integer serialization performance and implemented the `contains()` function. 156. [Michele Caini](https://github.com/skypjack) fixed links in the README.
157. [past-due](https://github.com/past-due) suppressed an unfixable warning. 157. [Hani](https://github.com/hnkb) documented how to install the library with NuGet.
158. [Elvis Oric](https://github.com/elvisoric) improved Meson support. 158. [yann-morin-1998](https://github.com/yann-morin-1998) helped to reduce the CMake requirement to version 3.1.
159. [Matěj Plch](https://github.com/Afforix) fixed an example in the README. 159. [Konstantin Podsvirov](https://github.com/podsvirov) maintains a package for the MSYS2 software distro and fixed the MSYS2 package documentation.
160. [Mark Beckwith](https://github.com/wythe) fixed a typo. 160. [remyabel](https://github.com/remyabel2) added GNUInstallDirs to the CMake files.
161. [scinart](https://github.com/scinart) fixed a bug in the serializer. 161. [Taylor Howard](https://github.com/taylorhoward92) fixed a unit test.
162. [Patrick Boettcher](https://github.com/pboettch) implemented `push_back()` and `pop_back()` for JSON Pointers. 162. [Gabe Ron](https://github.com/Macr0Nerd) implemented the `to_string` method.
163. [Bruno Oliveira](https://github.com/nicoddemus) added support for Conda. 163. [Watal M. Iwasaki](https://github.com/heavywatal) fixed a Clang warning.
164. [Michele Caini](https://github.com/skypjack) fixed links in the README. 164. [Viktor Kirilov](https://github.com/onqtam) switched the unit tests from [Catch](https://github.com/philsquared/Catch) to [doctest](https://github.com/doctest/doctest)
165. [Hani](https://github.com/hnkb) documented how to install the library with NuGet. 165. [Juncheng E](https://github.com/ejcjason) fixed a typo.
166. [Mark Beckwith](https://github.com/wythe) fixed a typo. 166. [tete17](https://github.com/tete17) fixed a bug in the `contains` function.
167. [yann-morin-1998](https://github.com/yann-morin-1998) helped to reduce the CMake requirement to version 3.1. 167. [Xav83](https://github.com/Xav83) fixed some cppcheck warnings.
168. [Konstantin Podsvirov](https://github.com/podsvirov) maintains a package for the MSYS2 software distro. 168. [0xflotus](https://github.com/0xflotus) fixed some typos.
169. [remyabel](https://github.com/remyabel2) added GNUInstallDirs to the CMake files. 169. [Christian Deneke](https://github.com/chris0x44) added a const version of `json_pointer::back`.
170. [Taylor Howard](https://github.com/taylorhoward92) fixed a unit test. 170. [Julien Hamaide](https://github.com/crazyjul) made the `items()` function work with custom string types.
171. [Gabe Ron](https://github.com/Macr0Nerd) implemented the `to_string` method. 171. [Evan Nemerson](https://github.com/nemequ) updated fixed a bug in Hedley and updated this library accordingly.
172. [Watal M. Iwasaki](https://github.com/heavywatal) fixed a Clang warning. 172. [Florian Pigorsch](https://github.com/flopp) fixed a lot of typos.
173. [Viktor Kirilov](https://github.com/onqtam) switched the unit tests from [Catch](https://github.com/philsquared/Catch) to [doctest](https://github.com/onqtam/doctest) 173. [Camille Bégué](https://github.com/cbegue) fixed an issue in the conversion from `std::pair` and `std::tuple` to `json`.
174. [Juncheng E](https://github.com/ejcjason) fixed a typo. 174. [Anthony VH](https://github.com/AnthonyVH) fixed a compile error in an enum deserialization.
175. [tete17](https://github.com/tete17) fixed a bug in the `contains` function. 175. [Yuriy Vountesmery](https://github.com/ua-code-dragon) noted a subtle bug in a preprocessor check.
176. [Xav83](https://github.com/Xav83) fixed some cppcheck warnings. 176. [Chen](https://github.com/dota17) fixed numerous issues in the library.
177. [0xflotus](https://github.com/0xflotus) fixed some typos. 177. [Antony Kellermann](https://github.com/aokellermann) added a CI step for GCC 10.1.
178. [Christian Deneke](https://github.com/chris0x44) added a const version of `json_pointer::back`. 178. [Alex](https://github.com/gistrec) fixed an MSVC warning.
179. [Julien Hamaide](https://github.com/crazyjul) made the `items()` function work with custom string types. 179. [Rainer](https://github.com/rvjr) proposed an improvement in the floating-point serialization in CBOR.
180. [Evan Nemerson](https://github.com/nemequ) updated fixed a bug in Hedley and updated this library accordingly. 180. [Francois Chabot](https://github.com/FrancoisChabot) made performance improvements in the input adapters.
181. [Florian Pigorsch](https://github.com/flopp) fixed a lot of typos. 181. [Arthur Sonzogni](https://github.com/ArthurSonzogni) documented how the library can be included via `FetchContent`.
182. [Camille Bégué](https://github.com/cbegue) fixed an issue in the conversion from `std::pair` and `std::tuple` to `json`. 182. [Rimas Misevičius](https://github.com/rmisev) fixed an error message.
183. [Anthony VH](https://github.com/AnthonyVH) fixed a compile error in an enum deserialization. 183. [Alexander Myasnikov](https://github.com/alexandermyasnikov) fixed some examples and a link in the README.
184. [Yuriy Vountesmery](https://github.com/ua-code-dragon) noted a subtle bug in a preprocessor check. 184. [Hubert Chathi](https://github.com/uhoreg) made CMake's version config file architecture-independent.
185. [Chen](https://github.com/dota17) fixed numerous issues in the library. 185. [OmnipotentEntity](https://github.com/OmnipotentEntity) implemented the binary values for CBOR, MessagePack, BSON, and UBJSON.
186. [Antony Kellermann](https://github.com/aokellermann) added a CI step for GCC 10.1. 186. [ArtemSarmini](https://github.com/ArtemSarmini) fixed a compilation issue with GCC 10 and fixed a leak.
187. [Alex](https://github.com/gistrec) fixed an MSVC warning. 187. [Evgenii Sopov](https://github.com/sea5kg) integrated the library to the wsjcpp package manager.
188. [Rainer](https://github.com/rvjr) proposed an improvement in the floating-point serialization in CBOR. 188. [Sergey Linev](https://github.com/linev) fixed a compiler warning.
189. [Francois Chabot](https://github.com/FrancoisChabot) made performance improvements in the input adapters. 189. [Miguel Magalhães](https://github.com/magamig) fixed the year in the copyright.
190. [Arthur Sonzogni](https://github.com/ArthurSonzogni) documented how the library can be included via `FetchContent`. 190. [Alexander “weej” Jones](https://github.com/alex-weej) fixed an example in the README.
191. [Rimas Misevičius](https://github.com/rmisev) fixed an error message. 191. [Antoine Cœur](https://github.com/Coeur) fixed some typos in the documentation.
192. [Alexander Myasnikov](https://github.com/alexandermyasnikov) fixed some examples and a link in the README. 192. [jothepro](https://github.com/jothepro) updated links to the Hunter package.
193. [Hubert Chathi](https://github.com/uhoreg) made CMake's version config file architecture-independent. 193. [Dave Lee](https://github.com/kastiglione) fixed a link in the README.
194. [OmnipotentEntity](https://github.com/OmnipotentEntity) implemented the binary values for CBOR, MessagePack, BSON, and UBJSON. 194. [Joël Lamotte](https://github.com/Klaim) added instruction for using Build2's package manager.
195. [ArtemSarmini](https://github.com/ArtemSarmini) fixed a compilation issue with GCC 10 and fixed a leak. 195. [Paul Jurczak](https://github.com/pauljurczak) fixed an example in the README.
196. [Evgenii Sopov](https://github.com/sea5kg) integrated the library to the wsjcpp package manager. 196. [Carlos Gomes Martinho](https://github.com/gocarlos) updated the Conan package source.
197. [Sergey Linev](https://github.com/linev) fixed a compiler warning. 197. [Tridacnid](https://github.com/Tridacnid) improved the CMake tests.
198. [Miguel Magalhães](https://github.com/magamig) fixed the year in the copyright. 198. [Michael](https://github.com/MBalszun) fixed MSVC warnings.
199. [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) fixed a compilation issue with MSVC. 199. [Quentin Barbarat](https://github.com/quentin-dev) fixed an example in the documentation.
200. [Alexander “weej” Jones](https://github.com/alex-weej) fixed an example in the README. 200. [XyFreak](https://github.com/XyFreak) fixed a compiler warning.
201. [Antoine Cœur](https://github.com/Coeur) fixed some typos in the documentation. 201. [TotalCaesar659](https://github.com/TotalCaesar659) fixed links in the README and updated the links in the documentation to use HTTPS.
202. [jothepro](https://github.com/jothepro) updated links to the Hunter package. 202. [Tanuj Garg](https://github.com/tanuj208) improved the fuzzer coverage for UBSAN input.
203. [Dave Lee](https://github.com/kastiglione) fixed a link in the README. 203. [AODQ](https://github.com/AODQ) fixed a compiler warning.
204. [Joël Lamotte](https://github.com/Klaim) added instruction for using Build2's package manager. 204. [jwittbrodt](https://github.com/jwittbrodt) made `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` inline.
205. [Paul Jurczak](https://github.com/pauljurczak) fixed an example in the README. 205. [pfeatherstone](https://github.com/pfeatherstone) improved the upper bound of arguments of the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.
206. [Sonu Lohani](https://github.com/sonulohani) fixed a warning. 206. [Jan Procházka](https://github.com/jprochazk) fixed a bug in the CBOR parser for binary and string values.
207. [Carlos Gomes Martinho](https://github.com/gocarlos) updated the Conan package source. 207. [T0b1-iOS](https://github.com/T0b1-iOS) fixed a bug in the new hash implementation.
208. [Konstantin Podsvirov](https://github.com/podsvirov) fixed the MSYS2 package documentation. 208. [Matthew Bauer](https://github.com/matthewbauer) adjusted the CBOR writer to create tags for binary subtypes.
209. [Tridacnid](https://github.com/Tridacnid) improved the CMake tests. 209. [gatopeich](https://github.com/gatopeich) implemented an ordered map container for `nlohmann::ordered_json`.
210. [Michael](https://github.com/MBalszun) fixed MSVC warnings. 210. [Érico Nogueira Rolim](https://github.com/ericonr) added support for pkg-config.
211. [Quentin Barbarat](https://github.com/quentin-dev) fixed an example in the documentation. 211. [KonanM](https://github.com/KonanM) proposed an implementation for the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.
212. [XyFreak](https://github.com/XyFreak) fixed a compiler warning. 212. [Guillaume Racicot](https://github.com/gracicot) implemented `string_view` support and allowed C++20 support.
213. [TotalCaesar659](https://github.com/TotalCaesar659) fixed links in the README. 213. [Alex Reinking](https://github.com/alexreinking) improved CMake support for `FetchContent`.
214. [Tanuj Garg](https://github.com/tanuj208) improved the fuzzer coverage for UBSAN input. 214. [Hannes Domani](https://github.com/ssbssa) provided a GDB pretty printer.
215. [AODQ](https://github.com/AODQ) fixed a compiler warning. 215. Lars Wirzenius reviewed the README file.
216. [jwittbrodt](https://github.com/jwittbrodt) made `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` inline. 216. [Jun Jie](https://github.com/ongjunjie) fixed a compiler path in the CMake scripts.
217. [pfeatherstone](https://github.com/pfeatherstone) improved the upper bound of arguments of the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros. 217. [Ronak Buch](https://github.com/rbuch) fixed typos in the documentation.
218. [Jan Procházka](https://github.com/jprochazk) fixed a bug in the CBOR parser for binary and string values. 218. [Alexander Karzhenkov](https://github.com/karzhenkov) fixed a move constructor and the Travis builds.
219. [T0b1-iOS](https://github.com/T0b1-iOS) fixed a bug in the new hash implementation. 219. [Leonardo Lima](https://github.com/leozz37) added CPM.Cmake support.
220. [Matthew Bauer](https://github.com/matthewbauer) adjusted the CBOR writer to create tags for binary subtypes. 220. [Joseph Blackman](https://github.com/jbzdarkid) fixed a warning.
221. [gatopeich](https://github.com/gatopeich) implemented an ordered map container for `nlohmann::ordered_json`. 221. [Yaroslav](https://github.com/YarikTH) updated doctest and implemented unit tests.
222. [Érico Nogueira Rolim](https://github.com/ericonr) added support for pkg-config. 222. [Martin Stump](https://github.com/globberwops) fixed a bug in the CMake files.
223. [KonanM](https://github.com/KonanM) proposed an implementation for the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros. 223. [Jaakko Moisio](https://github.com/jasujm) fixed a bug in the input adapters.
224. [Guillaume Racicot](https://github.com/gracicot) implemented `string_view` support and allowed C++20 support. 224. [bl-ue](https://github.com/bl-ue) fixed some Markdown issues in the README file.
225. [Alex Reinking](https://github.com/alexreinking) improved CMake support for `FetchContent`. 225. [William A. Wieselquist](https://github.com/wawiesel) fixed an example from the README.
226. [Hannes Domani](https://github.com/ssbssa) provided a GDB pretty printer. 226. [abbaswasim](https://github.com/abbaswasim) fixed an example from the README.
227. Lars Wirzenius reviewed the README file. 227. [Remy Jette](https://github.com/remyjette) fixed a warning.
228. [Jun Jie](https://github.com/ongjunjie) fixed a compiler path in the CMake scripts. 228. [Fraser](https://github.com/frasermarlow) fixed the documentation.
229. [Ronak Buch](https://github.com/rbuch) fixed typos in the documentation. 229. [Ben Beasley](https://github.com/musicinmybrain) updated doctest.
230. [Alexander Karzhenkov](https://github.com/karzhenkov) fixed a move constructor and the Travis builds. 230. [Doron Behar](https://github.com/doronbehar) fixed pkg-config.pc.
231. [Leonardo Lima](https://github.com/leozz37) added CPM.Cmake support. 231. [raduteo](https://github.com/raduteo) fixed a warning.
232. [Joseph Blackman](https://github.com/jbzdarkid) fixed a warning. 232. [David Pfahler](https://github.com/theShmoo) added the possibility to compile the library without I/O support.
233. [Yaroslav](https://github.com/YarikTH) updated doctest and implemented unit tests. 233. [Morten Fyhn Amundsen](https://github.com/mortenfyhn) fixed a typo.
234. [Martin Stump](https://github.com/globberwops) fixed a bug in the CMake files. 234. [jpl-mac](https://github.com/jpl-mac) allowed treating the library as a system header in CMake.
235. [Jaakko Moisio](https://github.com/jasujm) fixed a bug in the input adapters. 235. [Jason Dsouza](https://github.com/jasmcaus) fixed the indentation of the CMake file.
236. [bl-ue](https://github.com/bl-ue) fixed some Markdown issues in the README file. 236. [offa](https://github.com/offa) added a link to Conan Center to the documentation.
237. [William A. Wieselquist](https://github.com/wawiesel) fixed an example from the README. 237. [Rafail Giavrimis](https://github.com/grafail) fixed the Google Benchmark default branch.
238. [abbaswasim](https://github.com/abbaswasim) fixed an example from the README. 238. [Louis Dionne](https://github.com/ldionne) fixed a conversion operator.
239. [Remy Jette](https://github.com/remyjette) fixed a warning. 239. [justanotheranonymoususer](https://github.com/justanotheranonymoususer) made the examples in the README more consistent.
240. [Fraser](https://github.com/frasermarlow) fixed the documentation. 240. [Finkman](https://github.com/Finkman) suppressed some `-Wfloat-equal` warnings and fixed the debug pretty-printer.
241. [Ben Beasley](https://github.com/musicinmybrain) updated doctest. 241. [Ferry Huberts](https://github.com/fhuberts) fixed `-Wswitch-enum` warnings and fixed a typo.
242. [Doron Behar](https://github.com/doronbehar) fixed pkg-config.pc. 242. [Arseniy Terekhin](https://github.com/senyai) made the GDB pretty-printer robust against unset variable names.
243. [raduteo](https://github.com/raduteo) fixed a warning. 243. [Amir Masoud Abdol](https://github.com/amirmasoudabdol) updated the Homebrew command as nlohmann/json is now in homebrew-core.
244. [David Pfahler](https://github.com/theShmoo) added the possibility to compile the library without I/O support. 244. [Hallot](https://github.com/Hallot) fixed some `-Wextra-semi-stmt warnings`.
245. [Morten Fyhn Amundsen](https://github.com/mortenfyhn) fixed a typo. 245. [Giovanni Cerretani](https://github.com/gcerretani) fixed `-Wunused` warnings on `JSON_DIAGNOSTICS` and fixed a check for `std::filesystem`.
246. [jpl-mac](https://github.com/jpl-mac) allowed treating the library as a system header in CMake. 246. [Bogdan Popescu](https://github.com/Kapeli) hosts the [docset](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B) for offline documentation viewers.
247. [Jason Dsouza](https://github.com/jasmcaus) fixed the indentation of the CMake file. 247. [Carl Smedstad](https://github.com/carlsmedstad) fixed an assertion error when using `JSON_DIAGNOSTICS`.
248. [offa](https://github.com/offa) added a link to Conan Center to the documentation. 248. [miikka75](https://github.com/miikka75) provided an important fix to compile C++17 code with Clang 9.
249. [TotalCaesar659](https://github.com/TotalCaesar659) updated the links in the documentation to use HTTPS. 249. [Maarten Becker](https://github.com/kernie) fixed a warning for shadowed variables.
250. [Rafail Giavrimis](https://github.com/grafail) fixed the Google Benchmark default branch. 250. [Cristi Vîjdea](https://github.com/axnsan12) fixed typos in the `operator[]` documentation.
251. [Louis Dionne](https://github.com/ldionne) fixed a conversion operator. 251. [Alex Beregszaszi](https://github.com/axic) fixed spelling mistakes in comments.
252. [justanotheranonymoususer](https://github.com/justanotheranonymoususer) made the examples in the README more consistent. 252. [Dirk Stolle](https://github.com/striezel) fixed typos in the documentation.
253. [Finkman](https://github.com/Finkman) suppressed some `-Wfloat-equal` warnings. 253. [Daniel Albuschat](https://github.com/daniel-kun) corrected the parameter name in the `parse` documentation.
254. [Ferry Huberts](https://github.com/fhuberts) fixed `-Wswitch-enum` warnings. 254. [Prince Mendiratta](https://github.com/Prince-Mendiratta) fixed a link to the FAQ.
255. [Arseniy Terekhin](https://github.com/senyai) made the GDB pretty-printer robust against unset variable names. 255. [Florian Albrechtskirchinger](https://github.com/falbrechtskirchinger) implemented `std::string_view` support for object keys and made dozens of other improvements.
256. [Amir Masoud Abdol](https://github.com/amirmasoudabdol) updated the Homebrew command as nlohmann/json is now in homebrew-core. 256. [Qianqian Fang](https://github.com/fangq) implemented the Binary JData (BJData) format.
257. [Hallot](https://github.com/Hallot) fixed some `-Wextra-semi-stmt warnings`. 257. [pketelsen](https://github.com/pketelsen) added macros `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` and `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`.
258. [Giovanni Cerretani](https://github.com/gcerretani) fixed `-Wunused` warnings on `JSON_DIAGNOSTICS`. 258. [DarkZeros](https://github.com/DarkZeros) adjusted to code to not clash with Arduino defines.
259. [Bogdan Popescu](https://github.com/Kapeli) hosts the [docset](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B) for offline documentation viewers. 259. [flagarde](https://github.com/flagarde) fixed the output of `meta()` for MSVC.
260. [Carl Smedstad](https://github.com/carlsmedstad) fixed an assertion error when using `JSON_DIAGNOSTICS`. 260. [Dimitris Apostolou](https://github.com/rex4539) fixed a typo.
261. [miikka75](https://github.com/miikka75) provided an important fix to compile C++17 code with Clang 9. 261. [Michael Nosthoff](https://github.com/heinemml) fixed a typo.
262. [Maarten Becker](https://github.com/kernie) fixed a warning for shadowed variables. 262. [JungHoon Lee](https://github.com/jhnlee) fixed a typo.
263. [Cristi Vîjdea](https://github.com/axnsan12) fixed typos in the `operator[]` documentation. 263. [Faruk D.](https://github.com/fdiblen) fixed the CITATION.CFF file.
264. [Alex Beregszaszi](https://github.com/axic) fixed spelling mistakes in comments. 264. [Andrea Cocito](https://github.com/puffetto) added a clarification on macro usage to the documentation.
265. [Dirk Stolle](https://github.com/striezel) fixed typos in documentation. 265. [Krzysiek Karbowiak](https://github.com/kkarbowiak) refactored the tests to use `CHECK_THROWS_WITH_AS`.
266. [Daniel Albuschat](https://github.com/daniel-kun) corrected the parameter name in the `parse` documentation. 266. [Chaoqi Zhang](https://github.com/prncoprs) fixed a typo.
267. [Prince Mendiratta](https://github.com/Prince-Mendiratta) fixed a link to the FAQ. 267. [ivanovmp](https://github.com/ivanovmp) fixed a whitespace error.
268. [Florian Albrechtskirchinger](https://github.com/falbrechtskirchinger) implemented `std::string_view` support for object keys and made dozens of other improvements. 268. [KsaNL](https://github.com/KsaNL) fixed a build error when including `<windows.h>`.
269. [Qianqian Fang](https://github.com/fangq) implemented the Binary JData (BJData) format. 269. [Andrea Pappacoda](https://github.com/Tachi107) moved `.pc` and `.cmake` files to `share` directory.
270. [pketelsen](https://github.com/pketelsen) added macros `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` and `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`. 270. [Wolf Vollprecht](https://github.com/wolfv) added the `patch_inplace` function.
271. [DarkZeros](https://github.com/DarkZeros) adjusted to code to not clash with Arduino defines. 271. [Jake Zimmerman](https://github.com/jez) highlighted common usage patterns in the README file.
272. [flagarde](https://github.com/flagarde) fixed the output of `meta()` for MSVC. 272. [NN](https://github.com/NN---) added the Visual Studio output directory to `.gitignore`.
273. [Giovanni Cerretani](https://github.com/gcerretani) fixed a check for `std::filesystem`. 273. [Romain Reignier](https://github.com/romainreignier) improved the performance of the vector output adapter.
274. [Dimitris Apostolou](https://github.com/rex4539) fixed a typo. 274. [Mike](https://github.com/Mike-Leo-Smith) fixed the `std::iterator_traits`.
275. [Ferry Huberts](https://github.com/fhuberts) fixed a typo. 275. [Richard Hozák](https://github.com/richardhozak) added macro `JSON_NO_ENUM` to disable default enum conversions.
276. [Michael Nosthoff](https://github.com/heinemml) fixed a typo. 276. [vakokako](https://github.com/vakokako) fixed tests when compiling with C++20.
277. [JungHoon Lee](https://github.com/jhnlee) fixed a typo. 277. [Alexander “weej” Jones](https://github.com/alexweej) fixed an example in the README.
278. [Faruk D.](https://github.com/fdiblen) fixed the CITATION.CFF file. 278. [Eli Schwartz](https://github.com/eli-schwartz) added more files to the `include.zip` archive.
279. [Andrea Cocito](https://github.com/puffetto) added a clarification on macro usage to the documentation. 279. [Kevin Lu](https://github.com/kevinlul) fixed a compilation issue when typedefs with certain names were present.
280. [Krzysiek Karbowiak](https://github.com/kkarbowiak) refactored the tests to use `CHECK_THROWS_WITH_AS`. 280. [Trevor Hickey](https://github.com/luxe) improved the description of an example.
281. [Chaoqi Zhang](https://github.com/prncoprs) fixed a typo. 281. [Jef LeCompte](https://github.com/jef) updated the year in the README file.
282. [ivanovmp](https://github.com/ivanovmp) fixed a whitespace error. 282. [Alexandre Hamez](https://github.com/ahamez) fixed a warning.
283. [KsaNL](https://github.com/KsaNL) fixed a build error when including `<windows.h>`. 283. [Maninderpal Badhan](https://github.com/mbadhan) fixed a typo.
284. [Andrea Pappacoda](https://github.com/Tachi107) moved `.pc` and `.cmake` files to `share` directory. 284. [kevin--](https://github.com/kevin--) added a note to an example in the README file.
285. [Wolf Vollprecht](https://github.com/wolfv) added the `patch_inplace` function. 285. [I](https://github.com/wx257osn2) fixed a typo.
286. [Jake Zimmerman](https://github.com/jez) highlighted common usage patterns in the README file. 286. [Gregorio Litenstein](https://github.com/Lord-Kamina) fixed the Clang detection.
287. [NN](https://github.com/NN---) added the Visual Studio output directory to `.gitignore`. 287. [Andreas Smas](https://github.com/andoma) added a Doozer badge.
288. [Romain Reignier](https://github.com/romainreignier) improved the performance of the vector output adapter. 288. [WanCW](https://github.com/wancw) fixed the string conversion with Clang.
289. [Mike](https://github.com/Mike-Leo-Smith) fixed the `std::iterator_traits`. 289. [zhaohuaxishi](https://github.com/zhaohuaxishi) fixed a Doxygen error.
290. [Richard Hozák](https://github.com/richardhozak) added macro `JSON_NO_ENUM` to disable default enum conversions. 290. [emvivre](https://github.com/emvivre) removed an invalid parameter from CMake.
291. [vakokako](https://github.com/vakokako) fixed tests when compiling with C++20. 291. [Tobias Hermann](https://github.com/Dobiasd) fixed a link in the README file.
292. [Alexander “weej” Jones](https://github.com/alexweej) fixed an example in the README. 292. [Michael](https://github.com/traits) fixed a warning.
293. [Eli Schwartz](https://github.com/eli-schwartz) added more files to the `include.zip` archive. 293. [Ryan Mulder](https://github.com/ryanjmulder) added `ensure_ascii` to the `dump` function.
294. [Kevin Lu](https://github.com/kevinlul) fixed a compilation issue when typedefs with certain names were present. 294. [Muri Nicanor](https://github.com/murinicanor) fixed the `sed` discovery in the Makefile.
295. [Trevor Hickey](https://github.com/luxe) improved the description of an example. 295. [David Avedissian](https://github.com/dgavedissian) implemented SFINAE-friendly `iterator_traits`.
296. [Jef LeCompte](https://github.com/jef) updated the year in the README file. 296. [AQNOUCH Mohammed](https://github.com/aqnouch) fixed a typo in the README.
297. [Alexandre Hamez](https://github.com/ahamez) fixed a warning. 297. [Gareth Sylvester-Bradley](https://github.com/garethsb) added `operator/=` and `operator/` to construct JSON pointers.
298. [Maninderpal Badhan](https://github.com/mbadhan) fixed a typo. 298. [Michael Macnair](https://github.com/mykter) added support for afl-fuzz testing.
299. [kevin--](https://github.com/kevin--) added a note to an example in the README file. 299. [Berkus Decker](https://github.com/berkus) fixed a typo in the README.
300. [I](https://github.com/wx257osn2) fixed a typo. 300. [Illia Polishchuk](https://github.com/ilqvya) improved the CMake testing.
301. [Gregorio Litenstein](https://github.com/Lord-Kamina) fixed the Clang detection. 301. [Ikko Ashimine](https://github.com/eltociear) fixed two typos.
302. [Andreas Smas](https://github.com/andoma) added a Doozer badge. 302. [Raphael Grimm](https://github.com/barcode) added the possibility to define a custom base class.
303. [WanCW](https://github.com/wancw) fixed the string conversion with Clang. 303. [tocic](https://github.com/tocic) fixed typos in the documentation.
304. [zhaohuaxishi](https://github.com/zhaohuaxishi) fixed a Doxygen error. 304. [Vertexwahn](https://github.com/Vertexwahn) added Bazel build support.
305. [emvivre](https://github.com/emvivre) removed an invalid parameter from CMake. 305. [DavidKorczynski](https://github.com/DavidKorczynski) added a CIFuzz CI GitHub action.
306. [Tobias Hermann](https://github.com/Dobiasd) fixed a link in the README file. 306. [Florian Segginger](https://github.com/floriansegginger) bumped the years in the README.
307. [Michael](https://github.com/traits) fixed a warning. 307. [haadfida](https://github.com/haadfida) cleaned up the badges of used services.
308. [Ryan Mulder](https://github.com/ryanjmulder) added `ensure_ascii` to the `dump` function. 308. [Arsen Arsenović](https://github.com/ArsenArsen) fixed a build error.
309. [Muri Nicanor](https://github.com/murinicanor) fixed the `sed` discovery in the Makefile. 309. [theevilone45](https://github.com/theevilone45) fixed a typo in a CMake file.
310. [David Avedissian](https://github.com/dgavedissian) implemented SFINAE-friendly `iterator_traits`. 310. [Sergei Trofimovich](https://github.com/trofi) fixed the custom allocator support.
311. [AQNOUCH Mohammed](https://github.com/aqnouch) fixed a typo in the README. 311. [Joyce](https://github.com/joycebrum) fixed some security issues in the GitHub workflows.
312. [Gareth Sylvester-Bradley](https://github.com/garethsb) added `operator/=` and `operator/` to construct JSON pointers. 312. [Nicolas Jakob](https://github.com/njakob) add vcpkg version badge.
313. [Michael Macnair](https://github.com/mykter) added support for afl-fuzz testing. 313. [Tomerkm](https://github.com/Tomerkm) added tests.
314. [Berkus Decker](https://github.com/berkus) fixed a typo in the README. 314. [No.](https://github.com/tusooa) fixed the use of `get<>` calls.
315. [Illia Polishchuk](https://github.com/ilqvya) improved the CMake testing. 315. [taro](https://github.com/tarolling) fixed a typo in the `CODEOWNERS` file.
316. [Ikko Ashimine](https://github.com/eltociear) fixed a typo. 316. [Felix Yan](https://github.com/felixonmars) fixed a typo in the README.
317. [Raphael Grimm](https://github.com/barcode) added the possibility to define a custom base class. 317. [HO-COOH](https://github.com/HO-COOH) fixed a parenthesis in the documentation.
318. [tocic](https://github.com/tocic) fixed typos in the documentation. 318. [miny1233](https://github.com/miny1233) fixed a parenthesis in the documentation.
319. [Vertexwahn](https://github.com/Vertexwahn) added Bazel build support. 319. [tomalakgeretkal](https://github.com/tomalakgeretkal) fixed a compilation error.
320. [Dirk Stolle](https://github.com/striezel) fixed typos in the documentation. 320. [alferov](https://github.com/ALF-ONE) fixed a compilation error and fixed a version in the documentation.
321. [DavidKorczynski](https://github.com/DavidKorczynski) added a CIFuzz CI GitHub action. 321. [Craig Scott](https://github.com/craigscott-crascit) fixed a deprecation warning in CMake.
322. [Finkman](https://github.com/Finkman) fixed the debug pretty-printer. 322. [Vyacheslav Zhdanovskiy](https://github.com/ZeronSix) added macros for serialization-only types.
323. [Florian Segginger](https://github.com/floriansegginger) bumped the years in the README. 323. [Mathieu Westphal](https://github.com/mwestphal) fixed typos.
324. [haadfida](https://github.com/haadfida) cleaned up the badges of used services. 324. [scribam](https://github.com/scribam) fixed the MinGW workflow.
325. [Arsen Arsenović](https://github.com/ArsenArsen) fixed a build error. 325. [Aleksei Sapitskii](https://github.com/aleksproger) added support for Apple's Swift Package Manager.
326. [theevilone45](https://github.com/theevilone45) fixed a typo in a CMake file. 326. [Benjamin Buch](https://github.com/bebuch) fixed the installation path in CMake.
327. [Sergei Trofimovich](https://github.com/trofi) fixed the custom allocator support. 327. [Colby Haskell](https://github.com/colbychaskell) clarified the parse error message in case a file cannot be opened.
328. [Joyce](https://github.com/joycebrum) fixed some security issues in the GitHub workflows. 328. [Juan Carlos Arevalo Baeza](https://github.com/TheJCAB) fixed the enum conversion.
329. [Nicolas Jakob](https://github.com/njakob) add vcpkg version badge. 329. [ss](https://github.com/serge-s) fixed the amalgamation call.
330. [Tomerkm](https://github.com/Tomerkm) added tests. 330. [AniketDhemare](https://github.com/AniketDhemare) fixed a version in the documentation.
331. [No.](https://github.com/tusooa) fixed the use of `get<>` calls. 331. [Philip Müller](https://github.com/philip-paul-mueller) fixed an example.
332. [taro](https://github.com/tarolling) fixed a typo in the `CODEOWNERS` file. 332. [Leila Shcheglova](https://github.com/LeilaShcheglova) fixed a warning in a test.
333. [Ikko Eltociear Ashimine](https://github.com/eltociear) fixed a typo. 333. [Alex Prabhat Bara](https://github.com/alexprabhat99) fixed a function name in the documentation.
334. [Felix Yan](https://github.com/felixonmars) fixed a typo in the README. 334. [laterlaugh](https://github.com/laterlaugh) fixed some typos.
335. [HO-COOH](https://github.com/HO-COOH) fixed a parenthesis in the documentation. 335. [Yuanhao Jia](https://github.com/MrJia1997) fixed the GDB pretty printer.
336. [Ivor Wanders](https://github.com/iwanders) fixed the examples to catch exception by `const&`. 336. [Fallen_Breath](https://github.com/Fallen-Breath) fixed an example for JSON Pointer.
337. [miny1233](https://github.com/miny1233) fixed a parenthesis in the documentation. 337. [Nikhil Idiculla](https://github.com/tsnl) fixed some typos.
338. [tomalakgeretkal](https://github.com/tomalakgeretkal) fixed a compilation error. 338. [Griffin Myers](https://github.com/gmyers18) updated the Natvis file.
339. [alferov](https://github.com/ALF-ONE) fixed a compilation error. 339. [thetimr](https://github.com/thetimr) fixed a typo in the documentation.
340. [Craig Scott](https://github.com/craigscott-crascit) fixed a deprecation warning in CMake. 340. [Balazs Erseki](https://github.com/zerocukor287) fixed a URL in the contribution guidelines.
341. [Vyacheslav Zhdanovskiy](https://github.com/ZeronSix) added macros for serialization-only types. 341. [Niccolò Iardella](https://github.com/rotolof) added `NLOHMANN_DEFINE_DERIVED_TYPE_*` macros.
342. [Mathieu Westphal](https://github.com/mwestphal) fixed typos. 342. [Borislav Stanimirov](https://github.com/iboB) allowed overriding the CMake target name.
343. [scribam](https://github.com/scribam) fixed the MinGW workflow. 343. [Captain Crutches](https://github.com/captaincrutches) made `iterator_proxy_value` a `std::forward_iterator`.
344. [Aleksei Sapitskii](https://github.com/aleksproger) added support for Apple's Swift Package Manager. 344. [Fredrik Sandhei](https://github.com/fsandhei) added type conversion support for `std::optional`.
345. [Benjamin Buch](https://github.com/bebuch) fixed the installation path in CMake. 345. [jh96](https://github.com/jordan-hoang) added exceptions when `nullptr` is passed to `parse`.
346. [Colby Haskell](https://github.com/colbychaskell) clarified the parse error message in case a file cannot be opened. 346. [Stuart Gorman](https://github.com/StuartGorman) fixed number parsing when `EINTR` set in `errno`.
347. [Juan Carlos Arevalo Baeza](https://github.com/TheJCAB) fixed the enum conversion. 347. [Dylan Baker](https://github.com/dcbaker) generated a pkg-config file that follows the pkg-config conventions.
348. [alferov](https://github.com/ALF-ONE) fixed a version in the documentation. 348. [Tianyi Chen](https://github.com/TianyiChen) optimized the binary `get_number` implementation.
349. [ss](https://github.com/serge-s) fixed the amalgamation call. 349. [peng-wang-cn](https://github.com/peng-wang-cn) added type conversion support for multidimensional arrays.
350. [AniketDhemare](https://github.com/AniketDhemare) fixed a version in the documentation. 350. [Einars Netlis-Galejs](https://github.com/EinarsNG) added `ONLY_SERIALIZE` for `NLOHMANN_DEFINE_DERIVED_TYPE_*` macros.
351. [Philip Müller](https://github.com/philip-paul-mueller) fixed an example. 351. [Marcel](https://github.com/mering) removed `alwayslink=True` Bazel flag.
352. [Leila Shcheglova](https://github.com/LeilaShcheglova) fixed a warning in a test. 352. [Harinath Nampally](https://github.com/hnampally) added diagnostic positions to exceptions.
353. [Alex Prabhat Bara](https://github.com/alexprabhat99) fixed a function name in the documentation. 353. [Nissim Armand Ben Danan](https://github.com/NissimBendanan) fixed `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` with an empty JSON instance.
354. [laterlaugh](https://github.com/laterlaugh) fixed some typos. 354. [Michael Valladolid](https://github.com/codenut) added support for BSON uint64 serialization/deserialization.
355. [Yuanhao Jia](https://github.com/MrJia1997) fixed the GDB pretty printer. 355. [Nikhil](https://github.com/nikhilreddydev) updated the documentation.
356. [Fallen_Breath](https://github.com/Fallen-Breath) fixed an example for JSON Pointer. 356. [Nebojša Cvetković](https://github.com/nebkat) added support for BJDATA optimized binary array type.
357. [Nikhil Idiculla](https://github.com/tsnl) fixed some typos. 357. [Sushrut Shringarputale](https://github.com/sushshring) added support for diagnostic positions.
358. [Griffin Myers](https://github.com/gmyers18) updated the Natvis file. 358. [kimci86](https://github.com/kimci86) templated to `NLOHMANN_DEFINE_TYPE` macros to also support `ordered_json`.
359. [thetimr](https://github.com/thetimr) fixed a typo in the documentation. 359. [Richard Topchii](https://github.com/richardtop) added support for VisionOS in the Swift Package Manager.
360. [Balazs Erseki](https://github.com/zerocukor287) fixed a URL in the contribution guidelines. 360. [Robert Chisholm](https://github.com/Robadob) fixed a typo.
361. [Niccolò Iardella](https://github.com/rotolof) added `NLOHMANN_DEFINE_DERIVED_TYPE_*` macros. 361. [zjyhjqs](https://github.com/zjyhjqs) added CPack support.
362. [Borislav Stanimirov](https://github.com/iboB) allowed overriding the CMake target name. 362. [bitFiedler](https://github.com/bitFiedler) made GDB pretty printer work with Python 3.8.
363. [Captain Crutches](https://github.com/captaincrutches) made `iterator_proxy_value` a `std::forward_iterator`. 363. [Gianfranco Costamagna](https://github.com/LocutusOfBorg) fixed a compiler warning.
364. [Fredrik Sandhei](https://github.com/fsandhei) added type conversion support for `std::optional`. 364. [risa2000](https://github.com/risa2000) made `std::filesystem::path` conversion to/from UTF-8 encoded string explicit.
365. [jh96](https://github.com/jordan-hoang) added exceptions when `nullptr` is passed to `parse`. 365. [AM](https://github.com/maqnouch) fixed typos in the README.
366. [Stuart Gorman](https://github.com/StuartGorman) fixed number parsing when `EINTR` set in `errno`. 366. [dmenendez-gruposantander](https://github.com/dmenendez-gruposantander) fixed typos in the comments of the examples.
367. [Dylan Baker](https://github.com/dcbaker) generated a pkg-config file that follows the pkg-config conventions. 367. [Mihai Stan](https://github.com/mstan-xx) fixed comparisons against the literal `0`.
368. [Tianyi Chen](https://github.com/TianyiChen) optimized the binary `get_number` implementation. 368. [Matt Gumbel](https://github.com/intelmatt) fixed some `-Weffc++` warnings.
369. [peng-wang-cn](https://github.com/peng-wang-cn) added type conversion support for multidimensional arrays. 369. [vimpunk](https://github.com/vimpunk) moved a lambda out of an unevaluated context to support older compilers.
370. [Einars Netlis-Galejs](https://github.com/EinarsNG) added `ONLY_SERIALIZE` for `NLOHMANN_DEFINE_DERIVED_TYPE_*` macros. 370. [Chris Harris](https://github.com/cjh1) fixed the compilation with GCC 4.8.
371. [Marcel](https://github.com/mering) removed `alwayslink=True` Bazel flag. 371. [Palmer Dabbelt](https://github.com/palmer-dabbelt) generated and installed a pkg-config file.
372. [Harinath Nampally](https://github.com/hnampally) added diagnostic positions to exceptions. 372. [Gus Pozuelo](https://github.com/ap-viavi) made `ordered_map` compatible with GCC 5.5, Clang 3.6, and Xcode 9.
373. [Nissim Armand Ben Danan](https://github.com/NissimBendanan) fixed `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` with an empty JSON instance. 373. [AK](https://github.com/Lioncky) fixed an MSVC build error caused by the `min`/`max` macros from `windows.h`.
374. [Michael Valladolid](https://github.com/codenut) added support for BSON uint64 serialization/deserialization. 374. [Sergiu Deitsch](https://github.com/sergiud) provided a fallback for missing `char8_t` support.
375. [Nikhil](https://github.com/nikhilreddydev) updated the documentation. 375. [Xiaochuan Ye](https://github.com/XueSongTap) fixed `from_msgpack` for `std::byte` input by specializing `std::char_traits`.
376. [Nebojša Cvetković](https://github.com/nebkat) added support for BJDATA optimized binary array type. 376. [Ville Vesilehto](https://github.com/thevilledev) fixed an overflow in the BJData size calculation and rejected overflowing negative integers in CBOR.
377. [Sushrut Shringarputale](https://github.com/sushshring) added support for diagnostic positions. 377. [NmPassTHFan](https://github.com/nmpassthf) replaced the deprecated `std::is_trivial` for C++26.
378. [kimci86](https://github.com/kimci86) templated to `NLOHMANN_DEFINE_TYPE` macros to also support `ordered_json`. 378. [Chris Ever](https://github.com/chirsz-ever) added the `ignore_trailing_commas` parser option.
379. [Richard Topchii](https://github.com/richardtop) added support for VisionOS in the Swift Package Manager. 379. [Kuan-Fu Wu](https://github.com/kfwu1999) fixed the example code for `json_pointer` initialization.
380. [Robert Chisholm](https://github.com/Robadob) fixed a typo. 380. [David Kilzer](https://github.com/ddkilzer) added a missing header to the input adapters.
381. [zjyhjqs](https://github.com/zjyhjqs) added CPack support. 381. [Miko](https://github.com/mikomikotaishi) added proper C++20 module support, simplified the module API, and fixed missing exports.
382. [bitFiedler](https://github.com/bitFiedler) made GDB pretty printer work with Python 3.8. 382. [hitgirl](https://github.com/hitgil) fixed the CMake configuration when cross-compiling.
383. [Gianfranco Costamagna](https://github.com/LocutusOfBorg) fixed a compiler warning. 383. [Devon Thomas](https://github.com/ThomaDevOSU) mentioned the Artistic Style formatting in the contribution guidelines.
384. [risa2000](https://github.com/risa2000) made `std::filesystem::path` conversion to/from UTF-8 encoded string explicit. 384. [Erik Hu](https://github.com/Erikhu1) made Coveralls upload errors non-fatal in the CI.
385. [AM](https://github.com/maqnouch) fixed typos in the README. 385. [co63oc](https://github.com/co63oc) fixed typos.
386. [dmenendez-gruposantander](https://github.com/dmenendez-gruposantander) fixed typos in the comments of the examples. 386. [DmitriBogdanov](https://github.com/DmitriBogdanov) fixed broken package manager links in the documentation.
387. [Mihai Stan](https://github.com/mstan-xx) fixed comparisons against the literal `0`. 387. [Bander](https://github.com/banderzhm) improved the MSVC compatibility of the C++ modules.
388. [Matt Gumbel](https://github.com/intelmatt) fixed some `-Weffc++` warnings. 388. [Andy Choi](https://github.com/ccpong) removed an unnecessary `template` keyword before `get` in the README and the documentation.
389. [vimpunk](https://github.com/vimpunk) moved a lambda out of an unevaluated context to support older compilers. 389. [SamareshSingh](https://github.com/ssam18) fixed single-element brace initialization to copy/move instead of wrapping in an array, fixed the `WITH_DEFAULT` macros for `ordered_map`, and handled moved events in `serve_header.py`.
390. [Chris Harris](https://github.com/cjh1) fixed the compilation with GCC 4.8. 390. [Aditya](https://github.com/Lumowhisp) improved the documentation of the documentation generation.
391. [Palmer Dabbelt](https://github.com/palmer-dabbelt) generated and installed a pkg-config file. 391. [cheese1](https://github.com/cheese1) clarified the README.
392. [Gus Pozuelo](https://github.com/ap-viavi) made `ordered_map` compatible with GCC 5.5, Clang 3.6, and Xcode 9. 392. [KhloodElhossiny](https://github.com/khloodelhossiny) enabled `std::string_view` keys in `operator[]`.
393. [AK](https://github.com/Lioncky) fixed an MSVC build error caused by the `min`/`max` macros from `windows.h`. 393. [Charles Cabergs](https://github.com/cacharle) fixed a `-Wtautological-constant-out-of-range-compare` warning.
394. [Sergiu Deitsch](https://github.com/sergiud) provided a fallback for missing `char8_t` support. 394. [EALePain](https://github.com/EALePain) made the `std::tuple` conversion work with reference types such as `std::tie`.
395. [Xiaochuan Ye](https://github.com/XueSongTap) fixed `from_msgpack` for `std::byte` input by specializing `std::char_traits`. 395. [koala_oishi](https://github.com/chibi-dogs) fixed grammatical wording in the README.
396. [Ville Vesilehto](https://github.com/thevilledev) fixed an overflow in the BJData size calculation and rejected overflowing negative integers in CBOR. 396. [riccardoori11](https://github.com/riccardoori11) fixed a typo in the documentation.
397. [NmPassTHFan](https://github.com/nmpassthf) replaced the deprecated `std::is_trivial` for C++26. 397. [Swastik Bose](https://github.com/VasuBhakt) fixed the parent pointers after `update()` with `JSON_DIAGNOSTICS` and fixed the Doxygen autolinking of requirements.
398. [Chris Ever](https://github.com/chirsz-ever) added the `ignore_trailing_commas` parser option. 398. [trdesilva](https://github.com/trdesilva) added `front`, `pop_front`, and `push_front` to `json_pointer`.
399. [Kuan-Fu Wu](https://github.com/kfwu1999) fixed the example code for `json_pointer` initialization. 399. [Akhilesh Arora](https://github.com/akhilesharora) fixed an incomplete-type error with `ordered_json`.
400. [David Kilzer](https://github.com/ddkilzer) added a missing header to the input adapters. 400. [Hariom Phulre](https://github.com/hariomphulre) fixed the C++20 modules compilation with GCC.
401. [Miko](https://github.com/mikomikotaishi) added proper C++20 module support, simplified the module API, and fixed missing exports. 401. [Kirill Lokotkov](https://github.com/RUSLoker) fixed printing `long double` values.
402. [hitgirl](https://github.com/hitgil) fixed the CMake configuration when cross-compiling. 402. [George Sedov](https://github.com/radistmorse) added the `NLOHMANN_DEFINE_TYPE_*_WITH_NAMES` macros.
403. [Devon Thomas](https://github.com/ThomaDevOSU) mentioned the Artistic Style formatting in the contribution guidelines. 403. [Caillin Nugent](https://github.com/nugentcaillin) added the `NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` macro.
404. [Erik Hu](https://github.com/Erikhu1) made Coveralls upload errors non-fatal in the CI. 404. [Cosmin D.](https://github.com/drcosmin) fixed `std::filesystem::path` conversions and added an MSVC workaround for `std::unique_ptr`.
405. [co63oc](https://github.com/co63oc) fixed typos. 405. [Paul Dreik](https://github.com/pauldreik) fixed a test relying on implementation-specific behavior.
406. [DmitriBogdanov](https://github.com/DmitriBogdanov) fixed broken package manager links in the documentation. 406. [Daniel Falk](https://github.com/daniel-falk) added missing copyright notices to the SBOM.
407. [Bander](https://github.com/banderzhm) improved the MSVC compatibility of the C++ modules. 407. [Federico Sfriso](https://github.com/federicosfriso05-dotcom) added support for constructing JSON values from C++20 range views.
408. [Andy Choi](https://github.com/ccpong) removed an unnecessary `template` keyword before `get` in the README and the documentation. 408. [Luke Banicevic](https://github.com/banaboi) fixed corrupt BSON output for lengths exceeding `INT32_MAX`, cleaned up the BSON writer, and improved the documentation.
409. [SamareshSingh](https://github.com/ssam18) fixed single-element brace initialization to copy/move instead of wrapping in an array, fixed the `WITH_DEFAULT` macros for `ordered_map`, and handled moved events in `serve_header.py`. 409. [Patrick Armstrong](https://github.com/Patrick10199) updated the CBOR references and the half-precision float assertions.
410. [Aditya](https://github.com/Lumowhisp) improved the documentation of the documentation generation. 410. [Yash Bavadiya](https://github.com/xevrion) added checks to all BSON reads.
411. [cheese1](https://github.com/cheese1) clarified the README. 411. [hum4nBeing](https://github.com/hum4nBeing) fixed the overflow handling of high-precision numbers in UBJSON.
412. [KhloodElhossiny](https://github.com/khloodelhossiny) enabled `std::string_view` keys in `operator[]`. 412. [tomatotomata](https://github.com/tomatotomata) added checks for reading CBOR tagged subtypes.
413. [Charles Cabergs](https://github.com/cacharle) fixed a `-Wtautological-constant-out-of-range-compare` warning. 413. [YingqiDuan](https://github.com/YingqiDuan) documented the BSON interoperability.
414. [EALePain](https://github.com/EALePain) made the `std::tuple` conversion work with reference types such as `std::tie`. 414. [KBS](https://github.com/youdie006) documented the standards compliance and the strictness of `parse()` and `operator>>`.
415. [koala_oishi](https://github.com/chibi-dogs) fixed grammatical wording in the README. 415. [Petr Bělohlávek](https://github.com/petrbel) added Clang 21 and 22 to the CI.
416. [riccardoori11](https://github.com/riccardoori11) fixed a typo in the documentation. 416. [Dmitry Rantovov](https://github.com/darkdi) fixed the placement of a CBOR documentation block.
417. [Swastik Bose](https://github.com/VasuBhakt) fixed the parent pointers after `update()` with `JSON_DIAGNOSTICS` and fixed the Doxygen autolinking of requirements. 417. [ljcjclljc](https://github.com/ljcjclljc) fixed the comparison of large unsigned integers with signed integers.
418. [trdesilva](https://github.com/trdesilva) added `front`, `pop_front`, and `push_front` to `json_pointer`. 418. [Sahil Kamate](https://github.com/sahilkamate03) fixed the handling of CBOR tags 0-5 and 21-23.
419. [Akhilesh Arora](https://github.com/akhilesharora) fixed an incomplete-type error with `ordered_json`. 419. [Krishnanand G](https://github.com/Krishnanand-G) made the UBJSON writer reject `use_type` without `use_size`.
420. [Hariom Phulre](https://github.com/hariomphulre) fixed the C++20 modules compilation with GCC. 420. [whn](https://github.com/Whning0513) documented the lenient BSON input handling and corrected the complexity of `to_bson`.
421. [Kirill Lokotkov](https://github.com/RUSLoker) fixed printing `long double` values. 421. [elix3r](https://github.com/22elix3r) fixed `update()` with `merge_objects` when merging a primitive into an object.
422. [George Sedov](https://github.com/radistmorse) added the `NLOHMANN_DEFINE_TYPE_*_WITH_NAMES` macros. 422. [Avionic Harshit](https://github.com/avionicharshit-byte) made `diff()` linear when an array shrinks.
423. [Caillin Nugent](https://github.com/nugentcaillin) added the `NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` macro. 423. [Qatadaha Bin Matloob](https://github.com/qatcod) fixed comparisons between integers and floats and fixed unparsable BJData output.
424. [Cosmin D.](https://github.com/drcosmin) fixed `std::filesystem::path` conversions and added an MSVC workaround for `std::unique_ptr`. 424. [Wu Shuwen](https://github.com/dajiaohuang) removed an unused include.
425. [Paul Dreik](https://github.com/pauldreik) fixed a test relying on implementation-specific behavior.
426. [Daniel Falk](https://github.com/daniel-falk) added missing copyright notices to the SBOM.
427. [Federico Sfriso](https://github.com/federicosfriso05-dotcom) added support for constructing JSON values from C++20 range views.
428. [Luke Banicevic](https://github.com/banaboi) fixed corrupt BSON output for lengths exceeding `INT32_MAX`, cleaned up the BSON writer, and improved the documentation.
429. [Patrick Armstrong](https://github.com/Patrick10199) updated the CBOR references and the half-precision float assertions.
430. [Yash Bavadiya](https://github.com/xevrion) added checks to all BSON reads.
431. [hum4nBeing](https://github.com/hum4nBeing) fixed the overflow handling of high-precision numbers in UBJSON.
432. [tomatotomata](https://github.com/tomatotomata) added checks for reading CBOR tagged subtypes.
433. [YingqiDuan](https://github.com/YingqiDuan) documented the BSON interoperability.
434. [KBS](https://github.com/youdie006) documented the standards compliance and the strictness of `parse()` and `operator>>`.
435. [Petr Bělohlávek](https://github.com/petrbel) added Clang 21 and 22 to the CI.
436. [Dmitry Rantovov](https://github.com/darkdi) fixed the placement of a CBOR documentation block.
437. [ljcjclljc](https://github.com/ljcjclljc) fixed the comparison of large unsigned integers with signed integers.
438. [Sahil Kamate](https://github.com/sahilkamate03) fixed the handling of CBOR tags 0-5 and 21-23.
439. [Krishnanand G](https://github.com/Krishnanand-G) made the UBJSON writer reject `use_type` without `use_size`.
440. [whn](https://github.com/Whning0513) documented the lenient BSON input handling and corrected the complexity of `to_bson`.
441. [elix3r](https://github.com/22elix3r) fixed `update()` with `merge_objects` when merging a primitive into an object.
442. [Avionic Harshit](https://github.com/avionicharshit-byte) made `diff()` linear when an array shrinks.
443. [Qatadaha Bin Matloob](https://github.com/qatcod) fixed comparisons between integers and floats and fixed unparsable BJData output.
444. [Wu Shuwen](https://github.com/dajiaohuang) removed an unused include.
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
@@ -1879,21 +1861,28 @@ The library itself consists of a single header file licensed under the MIT licen
- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows - [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows
- [**Artistic Style**](https://astyle.sourceforge.net) for automatic source code indentation - [**Artistic Style**](https://astyle.sourceforge.net) for automatic source code indentation
- [**Clang**](https://clang.llvm.org) for compilation with code sanitizers - [**Clang**](https://clang.llvm.org) for compilation with code sanitizers
- [**Clang-Tidy**](https://clang.llvm.org/extra/clang-tidy/) for static analysis and style checks
- [**CMake**](https://cmake.org) for build automation - [**CMake**](https://cmake.org) for build automation
- [**Codacy**](https://www.codacy.com) for further [code analysis](https://app.codacy.com/gh/nlohmann/json/dashboard) - [**Codacy**](https://www.codacy.com) for further [code analysis](https://app.codacy.com/gh/nlohmann/json/dashboard)
- [**CodeQL**](https://codeql.github.com) for code scanning
- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json) - [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)
- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json) - [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)
- [**cppcheck**](https://cppcheck.sourceforge.io) for static analysis - [**cppcheck**](https://cppcheck.sourceforge.io) for static analysis
- [**doctest**](https://github.com/onqtam/doctest) for the unit tests - [**cpplint**](https://github.com/cpplint/cpplint) for style checks
- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md) - [**doctest**](https://github.com/doctest/doctest) for the unit tests
- [**Flawfinder**](https://dwheeler.com/flawfinder/) for static analysis
- [**GitHub Changelog Generator**](https://github.com/github-changelog-generator/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md)
- [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks - [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks
- [**Hedley**](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros - [**Hedley**](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros
- [**include-what-you-use**](https://include-what-you-use.org) to check the included headers
- [**Infer**](https://fbinfer.com) for static analysis
- [**lcov**](https://github.com/linux-test-project/lcov) to process coverage information and create an HTML view - [**lcov**](https://github.com/linux-test-project/lcov) to process coverage information and create an HTML view
- [**libFuzzer**](https://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz - [**libFuzzer**](https://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz
- [**Material for MkDocs**](https://squidfunk.github.io/mkdocs-material/) for the style of the documentation site - [**Material for MkDocs**](https://squidfunk.github.io/mkdocs-material/) for the style of the documentation site
- [**MkDocs**](https://www.mkdocs.org) for the documentation site - [**MkDocs**](https://www.mkdocs.org) for the documentation site
- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json)) - [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json))
- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments. - [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments.
- [**Semgrep**](https://semgrep.dev) for static analysis
- [**Valgrind**](https://valgrind.org) to check for correct memory management - [**Valgrind**](https://valgrind.org) to check for correct memory management
## Notes ## Notes
@@ -1987,10 +1976,10 @@ If the testdata is not found, several test suites will fail like this:
``` ```
=============================================================================== ===============================================================================
json/tests/src/make_test_data_available.hpp:21: json/tests/src/make_test_data_available.hpp:26:
TEST CASE: check test suite is downloaded TEST CASE: check test suite is downloaded
json/tests/src/make_test_data_available.hpp:23: FATAL ERROR: REQUIRE( utils::check_testsuite_downloaded() ) is NOT correct! json/tests/src/make_test_data_available.hpp:28: FATAL ERROR: REQUIRE( utils::check_testsuite_downloaded() ) is NOT correct!
values: REQUIRE( false ) values: REQUIRE( false )
logged: Test data not found in 'json/cmake-build-debug/json_test_data'. logged: Test data not found in 'json/cmake-build-debug/json_test_data'.
Please execute target 'download_test_data' before running this test suite. Please execute target 'download_test_data' before running this test suite.
@@ -2001,10 +1990,10 @@ json/tests/src/make_test_data_available.hpp:23: FATAL ERROR: REQUIRE( utils::che
In case you have downloaded the library rather than checked out the code via Git, test `cmake_fetch_content_configure` will fail. Please execute `ctest -LE git_required` to skip these tests. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information. In case you have downloaded the library rather than checked out the code via Git, test `cmake_fetch_content_configure` will fail. Please execute `ctest -LE git_required` to skip these tests. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.
Some tests are requiring network to be properly execute. They are labeled as `git_required`. Please execute `ctest -LE git_required` to skip these tests. See [issue #4851](https://github.com/nlohmann/json/issues/4851) for more information. Some tests require network access to execute properly. They are labeled as `git_required`. Please execute `ctest -LE git_required` to skip these tests. See [issue #4851](https://github.com/nlohmann/json/issues/4851) for more information.
Some tests change the installed files and hence make the whole process not reproducible. Please execute `ctest -LE not_reproducible` to skip these tests. See [issue #2324](https://github.com/nlohmann/json/issues/2324) for more information. Furthermore, assertions must be switched off to ensure reproducible builds (see [discussion 4494](https://github.com/nlohmann/json/discussions/4494)). Some tests change the installed files and hence make the whole process not reproducible. Please execute `ctest -LE not_reproducible` to skip these tests. See [issue #2324](https://github.com/nlohmann/json/issues/2324) for more information. Furthermore, assertions must be switched off to ensure reproducible builds (see [discussion 4494](https://github.com/nlohmann/json/discussions/4494)).
Note you need to call `cmake -LE "not_reproducible|git_required"` to exclude both labels. See [issue #2596](https://github.com/nlohmann/json/issues/2596) for more information. Note you need to call `ctest -LE "not_reproducible|git_required"` to exclude both labels. See [issue #2596](https://github.com/nlohmann/json/issues/2596) for more information.
As Intel compilers use unsafe floating point optimization by default, the unit tests may fail. Use flag [`/fp:precise`](https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/fp-model-fp.html) then. As Intel compilers use unsafe floating point optimization by default, the unit tests may fail. Use flag [`/fp:precise`](https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/fp-model-fp.html) then.
+8 -2
View File
@@ -10,10 +10,10 @@ SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me>"
SPDX-License-Identifier = "MIT" SPDX-License-Identifier = "MIT"
[[annotations]] [[annotations]]
path = "include/nlohmann/thirdparty/hedley.hpp" path = "include/nlohmann/thirdparty/hedley/hedley.hpp"
precedence = "aggregate" precedence = "aggregate"
SPDX-FileCopyrightText = "2016-2021 Evan Nemerson <evan@nemerson.com>" SPDX-FileCopyrightText = "2016-2021 Evan Nemerson <evan@nemerson.com>"
SPDX-License-Identifier = "CC0" SPDX-License-Identifier = "CC0-1.0"
[[annotations]] [[annotations]]
path = "include/nlohmann/detail/meta/cpp_future.hpp" path = "include/nlohmann/detail/meta/cpp_future.hpp"
@@ -50,3 +50,9 @@ path = "tools/gdb_pretty_printer/**"
precedence = "aggregate" precedence = "aggregate"
SPDX-FileCopyrightText = "2020 Hannes Domani <https://github.com/ssbssa>" SPDX-FileCopyrightText = "2020 Hannes Domani <https://github.com/ssbssa>"
SPDX-License-Identifier = "MIT" SPDX-License-Identifier = "MIT"
[[annotations]]
path = "docs/docset/icon*.png"
precedence = "override"
SPDX-FileCopyrightText = "JSON logo (public domain), https://commons.wikimedia.org/wiki/File:JSON_vector_logo.svg"
SPDX-License-Identifier = "CC0-1.0"
+21 -21
View File
@@ -5,15 +5,14 @@ set(N 10)
# Needed tools. # Needed tools.
############################################################################### ###############################################################################
include(FindPython3)
find_package(Python3 COMPONENTS Interpreter) find_package(Python3 COMPONENTS Interpreter)
find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-22 clang++-21 clang++-20 clang++-19 clang++-18 clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++) find_program(CLANG_TOOL NAMES clang++ clang++-HEAD clang++-22 clang++-21 clang++-20 clang++-19 clang++-18 clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11)
execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION) execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION)
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}") string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}")
message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})") message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})")
find_program(CLANG_TIDY_TOOL NAMES clang-tidy-22 clang-tidy-21 clang-tidy-20 clang-tidy-19 clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy) find_program(CLANG_TIDY_TOOL NAMES clang-tidy clang-tidy-22 clang-tidy-21 clang-tidy-20 clang-tidy-19 clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11)
execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION) execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION)
string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}") string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}")
message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})") message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})")
@@ -69,9 +68,7 @@ string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" VALGRIND_TOOL_VERSION "${VALGRIND_TOOL_V
message(STATUS "🔖 Valgrind ${VALGRIND_TOOL_VERSION} (${VALGRIND_TOOL})") message(STATUS "🔖 Valgrind ${VALGRIND_TOOL_VERSION} (${VALGRIND_TOOL})")
find_program(GENHTML_TOOL NAMES genhtml) find_program(GENHTML_TOOL NAMES genhtml)
find_program(PLOG_CONVERTER_TOOL NAMES plog-converter) find_program(SCAN_BUILD_TOOL NAMES scan-build scan-build-22 scan-build-21 scan-build-20 scan-build-19 scan-build-18 scan-build-17 scan-build-16 scan-build-15 scan-build-14 scan-build-13 scan-build-12 scan-build-11)
find_program(PVS_STUDIO_ANALYZER_TOOL NAMES pvs-studio-analyzer)
find_program(SCAN_BUILD_TOOL NAMES scan-build-15 scan-build-14 scan-build-13 scan-build-12 scan-build-11 scan-build)
# the individual source files # the individual source files
file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp) file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp)
@@ -367,7 +364,7 @@ add_custom_target(ci_test_coverage
COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc branch_coverage=1 --rc geninfo_unexecuted_blocks=1 --ignore-errors mismatch --ignore-errors unused COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc branch_coverage=1 --rc geninfo_unexecuted_blocks=1 --ignore-errors mismatch --ignore-errors unused
COMMAND ${LCOV_TOOL} -e json.info ${SRC_FILES} --output-file json.info.filtered --rc branch_coverage=1 --ignore-errors unused COMMAND ${LCOV_TOOL} -e json.info ${SRC_FILES} --output-file json.info.filtered --rc branch_coverage=1 --ignore-errors unused
COMMAND ${CMAKE_SOURCE_DIR}/tests/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept COMMAND ${CMAKE_SOURCE_DIR}/tests/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept
COMMAND genhtml --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.filtered.noexcept COMMAND ${GENHTML_TOOL} --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.filtered.noexcept
COMMENT "Compile and test with coverage" COMMENT "Compile and test with coverage"
) )
@@ -392,8 +389,8 @@ add_custom_target(ci_test_clang_sanitizer
# Check if header is amalgamated and sources are properly indented. # Check if header is amalgamated and sources are properly indented.
############################################################################### ###############################################################################
# Same file set as .github/workflows/check_amalgamation.yml, so a direct push to develop/master/release/* # Same file set as .github/workflows/check_amalgamation.yml, so this CMake target (which can be run locally) is held
# (which only this CMake target checks, not the pull_request-only workflow) is held to the same standard. # to the same standard as the workflow (which runs for pull requests and for pushes to develop/master/release/*).
file(GLOB_RECURSE INDENT_FILES file(GLOB_RECURSE INDENT_FILES
${PROJECT_SOURCE_DIR}/docs/mkdocs/docs/examples/*.hpp ${PROJECT_SOURCE_DIR}/docs/mkdocs/docs/examples/*.hpp
${PROJECT_SOURCE_DIR}/docs/mkdocs/docs/examples/*.cpp ${PROJECT_SOURCE_DIR}/docs/mkdocs/docs/examples/*.cpp
@@ -410,10 +407,11 @@ list(FILTER INDENT_FILES EXCLUDE REGEX "/tests/thirdparty/|/tests/abi/include/nl
set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann) set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann)
set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate) set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate)
add_custom_target(ci_test_amalgamation 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.hpp ${include_dir}/json.hpp~
COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.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_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 cp ${PROJECT_SOURCE_DIR}/BUILD.bazel ${PROJECT_SOURCE_DIR}/BUILD.bazel~
COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle
@@ -423,17 +421,21 @@ 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.json -s .
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.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 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_literals.hpp ${include_dir}/json_view.hpp
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/scripts/gen_bazel_build_file.cmake 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.hpp~ ${include_dir}/json.hpp
COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.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_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 diff ${PROJECT_SOURCE_DIR}/BUILD.bazel~ ${PROJECT_SOURCE_DIR}/BUILD.bazel
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES} COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES}
COMMAND for FILE in `find . -name '*.orig'`\; do false \; done COMMAND for FILE in `find . -name '*.orig'`\; do false \; done
COMMAND rm -f ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~ ${include_dir}/json_view.hpp~ ${PROJECT_SOURCE_DIR}/BUILD.bazel~
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Check amalgamation, formatting, and BUILD.bazel" COMMENT "Check amalgamation, formatting, and BUILD.bazel"
) )
@@ -719,7 +721,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 # 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 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_DisableTupleReferenceConversion JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind
JSON_StrictNulHandling JSON_StrictBinaryUTF8 JSON_DeleteDeprecatedFunctions) 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_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}) set(JSON_CMAKE_FLAGS_4_0_0 JSON_BuildTests ${JSON_CMAKE_FLAGS_3_5_0})
@@ -776,17 +778,14 @@ add_custom_target(ci_cmake_flags
# Use more installed compilers. # Use more installed compilers.
############################################################################### ###############################################################################
foreach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6 g++-7 g++-8 g++-9 g++-10 g++-11 clang++-3.5 clang++-3.6 clang++-3.7 clang++-3.8 clang++-3.9 clang++-4.0 clang++-5.0 clang++-6.0 clang++-7 clang++-8 clang++-9 clang++-10 clang++-11 clang++-12 clang++-13 clang++-14 clang++-15 clang++-16 clang++-17 clang++-18 clang++-19 clang++-20) foreach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6)
find_program(COMPILER_TOOL NAMES ${COMPILER}) find_program(COMPILER_TOOL NAMES ${COMPILER})
if (COMPILER_TOOL) if (COMPILER_TOOL)
unset(ADDITIONAL_FLAGS)
add_custom_target(ci_test_compiler_${COMPILER} add_custom_target(ci_test_compiler_${COMPILER}
COMMAND CXX=${COMPILER} ${CMAKE_COMMAND} COMMAND CXX=${COMPILER} ${CMAKE_COMMAND}
-DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_BUILD_TYPE=Debug -GNinja
-DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_BuildTests=ON -DJSON_FastTests=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
${ADDITIONAL_FLAGS}
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --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}" COMMENT "Compile and test with ${COMPILER}"
@@ -800,7 +799,6 @@ add_custom_target(ci_test_compiler_default
-DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_BUILD_TYPE=Debug -GNinja
-DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_BuildTests=ON -DJSON_FastTests=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_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 ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_default --parallel ${N}
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_default && ${CMAKE_CTEST_COMMAND} --parallel ${N} -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" COMMENT "Compile and test with default C++ compiler"
@@ -823,10 +821,12 @@ add_custom_target(ci_cuda_example
add_custom_target(ci_module_cpp20 add_custom_target(ci_module_cpp20
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
-DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_BUILD_TYPE=Debug -GNinja
-DJSON_CI=ON -DNLOHMANN_JSON_BUILD_MODULES=ON -DJSON_Install=ON -DJSON_CI=ON -DNLOHMANN_JSON_BUILD_MODULES=ON -DJSON_Install=ON
"-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
-S${PROJECT_SOURCE_DIR}/tests/module_cpp20 -B${PROJECT_BINARY_DIR}/ci_module_cpp20 -S${PROJECT_SOURCE_DIR}/tests/module_cpp20 -B${PROJECT_BINARY_DIR}/ci_module_cpp20
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/ci_module_cpp20 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/ci_module_cpp20
VERBATIM
) )
############################################################################### ###############################################################################
@@ -871,11 +871,11 @@ add_custom_target(ci_icpx
# The following tests are excluded as they trigger known nvc++ 25.5 defects (not # The following tests are excluded as they trigger known nvc++ 25.5 defects (not
# library bugs); see https://github.com/nlohmann/json for tracking. Only the # library bugs); see https://github.com/nlohmann/json for tracking. Only the
# affected language-standard variants are excluded so coverage is otherwise kept: # affected language-standard variants are excluded so coverage is otherwise kept:
# - test-comparison-cpp20_cpp20, test-comparison_legacy-cpp20_cpp20 # - test-comparison_cpp20, test-comparison_legacy_cpp20
# miscompiles cross-type/<=> comparison (e.g. `-17 <= null`) # miscompiles cross-type/<=> comparison (e.g. `-17 <= null`)
# - test-constructor1_cpp11 # - test-constructor1_cpp11
# std::initializer_list lifetime bug -> SIGSEGV # std::initializer_list lifetime bug -> SIGSEGV
# - test-deserialization-cpp20_cpp20 # - test-deserialization_cpp20
# mangles the UTF-8 u8"" string literal in the char8_t (C++20) section # mangles the UTF-8 u8"" string literal in the char8_t (C++20) section
add_custom_target(ci_nvhpc add_custom_target(ci_nvhpc
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
@@ -887,7 +887,7 @@ add_custom_target(ci_nvhpc
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_nvhpc COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_nvhpc
# the pipes are escaped so the surrounding shell passes them to ctest verbatim # the pipes are escaped so the surrounding shell passes them to ctest verbatim
# instead of treating them as shell pipe operators # instead of treating them as shell pipe operators
COMMAND cd ${PROJECT_BINARY_DIR}/build_nvhpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-comparison-cpp20_cpp20\\|test-comparison_legacy-cpp20_cpp20\\|test-constructor1_cpp11\\|test-deserialization-cpp20_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++)" COMMENT "Compile and test with NVIDIA HPC SDK (nvc++)"
) )
+6
View File
@@ -4,5 +4,11 @@
# call converts -1 to size_t, which -fsanitize=integer reports as implicit-integer-sign-change. This is # 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 # 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. # 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] [implicit-integer-sign-change]
src:*/include/c++/*/format src:*/include/c++/*/format
src:*/include/c++/*/string_view
+2
View File
@@ -49,6 +49,8 @@ cc_library(
hdrs = [ hdrs = [
"single_include/nlohmann/json.hpp", "single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp", "single_include/nlohmann/json_fwd.hpp",
"single_include/nlohmann/json_literals.hpp",
"single_include/nlohmann/json_view.hpp",
], ],
includes = ["single_include"], includes = ["single_include"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
+39 -366
View File
@@ -109,55 +109,6 @@ function(_json_test_apply_test_properties test_target properties_target)
endif() endif()
endfunction() endfunction()
# for internal use by _json_test_add_test() and _json_test_add_unity_batch():
# registers the CTest test <test_name>_cpp<cxx_standard> (plus its Valgrind
# variant), which runs the executable target <test_target> with the arguments
# in ARGN, and applies the test properties of the test- and standard-specific
# interface targets
function(_json_test_register_test test_name test_target cxx_standard)
set(ctest_name ${test_name}_cpp${cxx_standard})
if (JSON_FastTests)
add_test(NAME ${ctest_name}
COMMAND ${test_target} ${DOCTEST_TEST_FILTER} ${ARGN}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
else()
add_test(NAME ${ctest_name}
COMMAND ${test_target} ${DOCTEST_TEST_FILTER} ${ARGN} --no-skip
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif()
set_tests_properties(${ctest_name} PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
# apply standard-specific test properties
if(TARGET _json_test_interface__cpp_${cxx_standard})
_json_test_apply_test_properties(${ctest_name} _json_test_interface__cpp_${cxx_standard})
endif()
# apply test-specific test properties
if(TARGET _json_test_interface_${test_name})
_json_test_apply_test_properties(${ctest_name} _json_test_interface_${test_name})
endif()
# apply test- and standard-specific test properties
if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard})
_json_test_apply_test_properties(${ctest_name}
_json_test_interface_${test_name}_cpp_${cxx_standard}
)
endif()
if(JSON_Valgrind)
add_test(NAME ${ctest_name}_valgrind
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER} ${ARGN}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
set_tests_properties(${ctest_name}_valgrind PROPERTIES
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
)
endif()
endfunction()
# for internal use by json_test_add_test_for() # for internal use by json_test_add_test_for()
function(_json_test_add_test test_name file main cxx_standard) function(_json_test_add_test test_name file main cxx_standard)
set(test_target ${test_name}_cpp${cxx_standard}) set(test_target ${test_name}_cpp${cxx_standard})
@@ -192,7 +143,45 @@ function(_json_test_add_test test_name file main cxx_standard)
) )
endif() endif()
_json_test_register_test(${test_name} ${test_target} ${cxx_standard}) if (JSON_FastTests)
add_test(NAME ${test_target}
COMMAND ${test_target} ${DOCTEST_TEST_FILTER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
else()
add_test(NAME ${test_target}
COMMAND ${test_target} ${DOCTEST_TEST_FILTER} --no-skip
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif()
set_tests_properties(${test_target} PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
# apply standard-specific test properties
if(TARGET _json_test_interface__cpp_${cxx_standard})
_json_test_apply_test_properties(${test_target} _json_test_interface__cpp_${cxx_standard})
endif()
# apply test-specific test properties
if(TARGET _json_test_interface_${test_name})
_json_test_apply_test_properties(${test_target} _json_test_interface_${test_name})
endif()
# apply test- and standard-specific test properties
if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard})
_json_test_apply_test_properties(${test_target}
_json_test_interface_${test_name}_cpp_${cxx_standard}
)
endif()
if(JSON_Valgrind)
add_test(NAME ${test_target}_valgrind
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
set_tests_properties(${test_target}_valgrind PROPERTIES
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
)
endif()
endfunction() endfunction()
############################################################################# #############################################################################
@@ -211,14 +200,6 @@ endfunction()
# Use NAME <name> to override the filename-derived test name. # Use NAME <name> to override the filename-derived test name.
# Use FORCE to create the test regardless of the file containing # Use FORCE to create the test regardless of the file containing
# JSON_HAS_CPP_<version_number>. # JSON_HAS_CPP_<version_number>.
#
# Tests that depend on the C++ standard (e.g., because they use the macros
# JSON_HAS_FILESYSTEM, JSON_HAS_RANGES, or JSON_HAS_THREE_WAY_COMPARISON)
# should not make the whole of a large unit-foo.cpp be rebuilt for every
# standard. Put them into a separate file unit-foo-cpp<NN>.cpp (see, e.g.,
# unit-items-cpp17.cpp) which wraps its content in #ifdef JSON_HAS_CPP_<NN>.
# Then, unit-foo.cpp itself contains no JSON_HAS_CPP_<NN> and is only built for
# C++11.
# Test targets are linked against <main>. # Test targets are linked against <main>.
# CXX_STANDARDS defaults to "11". # CXX_STANDARDS defaults to "11".
############################################################################# #############################################################################
@@ -262,314 +243,6 @@ function(json_test_add_test_for file)
endforeach() endforeach()
endfunction() endfunction()
# for internal use by json_test_add_unity_tests(): sets <result> to whether the
# (absolute) <file> is built for <cxx_standard>; same rule as in
# json_test_add_test_for(): C++11 always, others only if the file contains
# JSON_HAS_CPP_<cxx_standard> or <force> is set
function(_json_test_unity_applies file cxx_standard force result)
set(${result} TRUE PARENT_SCOPE)
if(NOT ("${cxx_standard}" STREQUAL 11 OR force))
file(READ ${file} file_content)
string(FIND "${file_content}" JSON_HAS_CPP_${cxx_standard} has_cpp_found)
if(${has_cpp_found} EQUAL -1)
set(${result} FALSE PARENT_SCOPE)
endif()
endif()
endfunction()
# for internal use by json_test_add_unity_tests(): creates the executable
# test-unity-<batch_name>_cpp<cxx_standard> from the (absolute) source files
# in ARGN, which are #include-d by a generated source file, and registers one
# CTest test per source file that runs only the test cases of that file; if
# <private> is true, the generated file defines JSON_TESTS_PRIVATE first
function(_json_test_add_unity_batch batch_name cxx_standard main private)
set(batch_target test-unity-${batch_name}_cpp${cxx_standard})
set(batch_source ${PROJECT_BINARY_DIR}/tests/unity/${batch_target}.cpp)
set(batch_content "// generated by cmake/test.cmake; do not edit\n")
if(private)
string(APPEND batch_content "// at least one file of this batch needs access to private members of the library\n")
string(APPEND batch_content "#define JSON_TESTS_PRIVATE\n")
# the files define the macro again; mark this definition as used, as
# -Wunused-macros reports an unused definition when it is redefined
string(APPEND batch_content "#ifdef JSON_TESTS_PRIVATE\n#endif\n")
endif()
foreach(file ${ARGN})
string(APPEND batch_content "#include \"${file}\" // NOLINT(bugprone-suspicious-include)\n")
endforeach()
# only touch the generated file if it changed to keep incremental builds incremental
set(old_content "")
if(EXISTS ${batch_source})
file(READ ${batch_source} old_content)
endif()
if(NOT "${old_content}" STREQUAL "${batch_content}")
file(WRITE ${batch_source} "${batch_content}")
endif()
add_executable(${batch_target} ${batch_source})
target_link_libraries(${batch_target} PRIVATE ${main})
set_target_properties(${batch_target} PROPERTIES
CXX_STANDARD ${cxx_standard}
CXX_STANDARD_REQUIRED ON
)
if(TARGET _json_test_interface__cpp_${cxx_standard})
target_link_libraries(${batch_target} PRIVATE _json_test_interface__cpp_${cxx_standard})
endif()
# rebuild the batch when one of its files changes, and show the files in IDEs;
# files that are also built standalone (VARIANT_FILES) are left out, as
# HEADER_FILE_ONLY is a per-file property and would also affect those targets
set_source_files_properties(${batch_source} PROPERTIES OBJECT_DEPENDS "${ARGN}")
foreach(file ${ARGN})
if(NOT file IN_LIST _json_test_unity_variant_files)
set_source_files_properties(${file} PROPERTIES HEADER_FILE_ONLY ON)
target_sources(${batch_target} PRIVATE ${file})
endif()
endforeach()
foreach(file ${ARGN})
get_filename_component(file_basename ${file} NAME_WE)
string(REGEX REPLACE "unit-(.+)" "test-\\1" test_name ${file_basename})
# run only the test cases defined in this file (and in the shared
# make_test_data_available.hpp if the file uses it)
file(READ ${file} file_content)
set(source_filter "--source-file=*${file_basename}.cpp")
string(FIND "${file_content}" make_test_data_available.hpp uses_test_data)
if(NOT ${uses_test_data} EQUAL -1)
string(APPEND source_filter ",*make_test_data_available.hpp")
endif()
_json_test_register_test(${test_name} ${batch_target} ${cxx_standard} "${source_filter}")
endforeach()
endfunction()
#############################################################################
# json_test_add_unity_tests(
# FILES <files>...
# MAIN <main>
# [CXX_STANDARDS <version_number>...] [FORCE]
# [BATCH_SIZE <size>]
# [GROUPS <group>...]
# [VARIANT_FILES <files>...])
#
# Like calling json_test_add_test_for(<file> MAIN <main> ...) for each of the
# <files>, but compiles several files together to speed up the build: for each
# C++ standard, the files are split into batches of <size> files (default: 8)
# and each batch is built as a single executable
#
# test-unity-<pool><index>_cpp<version_number>
#
# whose generated source file #include-s the files of the batch (so they share
# the template instantiations of the library). The tests are still named
# test-foo_cpp<version_number>, one per file, but run the batch executable with
# a doctest filter that selects the test cases of that file only.
#
# Files are only batched with files that agree on the macros defined before
# the library is included: files that define at most JSON_TESTS_PRIVATE (or
# macros derived from global compile definitions) form the pools "plain" and
# "private". All other files are added with json_test_add_test_for() as usual,
# as are files with test-specific build settings (see
# json_test_set_test_options()) and the files listed in the explicit
# exclusion list below.
# Each <group> names a list variable json_test_unity_group_<group> of test file
# stems (file names without "unit-" and ".cpp"). The batchable files of a group
# are compiled together (regardless of BATCH_SIZE) as one executable
#
# test-unity-<group>_cpp<version_number>
#
# so that related tests, which instantiate the same templates, share one
# translation unit. A group may mix the pools "plain" and "private"; if any of
# its files needs JSON_TESTS_PRIVATE, the whole group is built with it. Files
# that cannot be batched stay standalone even if they are listed in a group.
# Files in no group are batched by BATCH_SIZE as described above.
# <files> in VARIANT_FILES are also built standalone with other settings, so
# they are not marked as header-only sources of the batch.
#############################################################################
function(json_test_add_unity_tests)
cmake_parse_arguments(args "FORCE" "MAIN;BATCH_SIZE" "FILES;CXX_STANDARDS;VARIANT_FILES;GROUPS" ${ARGN})
if("${args_MAIN}" STREQUAL "")
message(FATAL_ERROR "Required argument MAIN <main> missing.")
endif()
if("${args_BATCH_SIZE}" STREQUAL "")
set(args_BATCH_SIZE 8)
endif()
if("${args_CXX_STANDARDS}" STREQUAL "")
set(args_CXX_STANDARDS 11)
endif()
if(args_FORCE)
set(force FORCE)
else()
set(force "")
endif()
set(_json_test_unity_variant_files "")
foreach(file ${args_VARIANT_FILES})
get_filename_component(file ${file} ABSOLUTE)
list(APPEND _json_test_unity_variant_files ${file})
endforeach()
# files that must not be merged into a batch: unit-32bit.cpp is only built
# for 32bit targets, and unit-no-macro-leak.cpp checks that including the
# library defines no unprefixed macro, which any other file would disturb
set(standalone_files unit-32bit.cpp unit-no-macro-leak.cpp)
set(harmless_macros "^(DOCTEST_.*|SKIP_TESTS_FOR_.*|JSON_TEST_DEPRECATED_FUNCTIONS_DELETED|JSON_TEST_STRICT_NUL_HANDLING_ENABLED|JSON_TEST_STRINGIZE)$")
# classify the files
set(plain_files "")
set(private_files "")
set(standalone_abs_files "")
foreach(file ${args_FILES})
get_filename_component(file_name ${file} NAME)
get_filename_component(file_basename ${file} NAME_WE)
string(REGEX REPLACE "unit-(.+)" "test-\\1" test_name ${file_basename})
set(batchable TRUE)
if(file_name IN_LIST standalone_files)
set(batchable FALSE)
endif()
if(TARGET _json_test_interface_${test_name})
set(batchable FALSE)
endif()
foreach(cxx_standard ${args_CXX_STANDARDS})
if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard})
set(batchable FALSE)
endif()
endforeach()
# files that suppress GCC's -Wnoexcept around their include of the
# library: the suppression has no effect once another file of the
# batch included the library first
if(batchable)
file(READ ${file} file_content)
string(FIND "${file_content}" "SUPPRESS_WARNING(\"-Wnoexcept\")" suppresses_noexcept)
if(NOT ${suppresses_noexcept} EQUAL -1)
set(batchable FALSE)
endif()
endif()
set(pool plain)
if(batchable)
# collect the macros (un)defined before the library is included
file(READ ${file} file_content)
string(FIND "${file_content}" "#include <nlohmann/" include_position)
if(NOT ${include_position} EQUAL -1)
string(SUBSTRING "${file_content}" 0 ${include_position} file_content)
endif()
string(REGEX MATCHALL "(^|\n)[ \t]*#[ \t]*(define|undef)[ \t]+[A-Za-z_0-9]+" directives "${file_content}")
foreach(directive ${directives})
string(REGEX REPLACE "^.*[ \t]([A-Za-z_0-9]+)$" "\\1" macro "${directive}")
if(macro MATCHES "${harmless_macros}")
continue()
elseif("${macro}" STREQUAL JSON_TESTS_PRIVATE)
set(pool private)
else()
set(batchable FALSE)
endif()
endforeach()
endif()
get_filename_component(file_abs ${file} ABSOLUTE)
if(NOT batchable)
list(APPEND standalone_abs_files ${file_abs})
json_test_add_test_for(${file} MAIN ${args_MAIN} CXX_STANDARDS ${args_CXX_STANDARDS} ${force})
continue()
endif()
get_filename_component(file ${file} ABSOLUTE)
list(APPEND ${pool}_files ${file})
endforeach()
# resolve the explicit groups: group_<name>_files are the (absolute) files
# of the group, group_<name>_private tells whether one of them is private
set(grouped_files "")
foreach(group ${args_GROUPS})
if(NOT DEFINED json_test_unity_group_${group})
message(FATAL_ERROR "Unity test group '${group}' is not defined (json_test_unity_group_${group}).")
endif()
set(group_${group}_files "")
set(group_${group}_private FALSE)
foreach(stem ${json_test_unity_group_${group}})
# check against the source directory, because FILES may be filtered (JSON_TestShard)
get_filename_component(file ${CMAKE_CURRENT_SOURCE_DIR}/src/unit-${stem}.cpp ABSOLUTE)
if(NOT EXISTS ${file})
message(FATAL_ERROR "Unity test group '${group}' lists '${stem}', but ${file} does not exist.")
endif()
if(file IN_LIST grouped_files)
message(FATAL_ERROR "Unity test file unit-${stem}.cpp is listed in more than one group (second: '${group}').")
endif()
list(APPEND grouped_files ${file})
if(file IN_LIST standalone_abs_files)
message(STATUS "Unity test group '${group}': unit-${stem}.cpp cannot be batched and stays standalone")
elseif(file IN_LIST plain_files)
list(APPEND group_${group}_files ${file})
list(REMOVE_ITEM plain_files ${file})
elseif(file IN_LIST private_files)
list(APPEND group_${group}_files ${file})
list(REMOVE_ITEM private_files ${file})
set(group_${group}_private TRUE)
endif()
endforeach()
endforeach()
foreach(cxx_standard ${args_CXX_STANDARDS})
if(NOT compiler_supports_cpp_${cxx_standard})
continue()
endif()
# explicit groups: one batch per group
foreach(group ${args_GROUPS})
set(batch_files "")
foreach(file ${group_${group}_files})
_json_test_unity_applies(${file} ${cxx_standard} "${force}" applies)
if(applies)
list(APPEND batch_files ${file})
endif()
endforeach()
if(batch_files)
_json_test_add_unity_batch(${group} ${cxx_standard} ${args_MAIN} ${group_${group}_private} ${batch_files})
endif()
endforeach()
# remaining files: batches of BATCH_SIZE files per pool
foreach(pool plain private)
set(is_private FALSE)
if(pool STREQUAL private)
set(is_private TRUE)
endif()
set(batch_files "")
set(batch_count 0)
set(batch_index 0)
foreach(file ${${pool}_files})
_json_test_unity_applies(${file} ${cxx_standard} "${force}" applies)
if(NOT applies)
continue()
endif()
list(APPEND batch_files ${file})
math(EXPR batch_count "${batch_count} + 1")
if(batch_count EQUAL args_BATCH_SIZE)
_json_test_add_unity_batch(${pool}${batch_index} ${cxx_standard} ${args_MAIN} ${is_private} ${batch_files})
set(batch_files "")
set(batch_count 0)
math(EXPR batch_index "${batch_index} + 1")
endif()
endforeach()
if(batch_files)
_json_test_add_unity_batch(${pool}${batch_index} ${cxx_standard} ${args_MAIN} ${is_private} ${batch_files})
endif()
endforeach()
endforeach()
endfunction()
############################################################################# #############################################################################
# json_test_should_build_32bit_test( # json_test_should_build_32bit_test(
# <build_32bit_var> <build_32bit_only_var> <input>) # <build_32bit_var> <build_32bit_only_var> <input>)
+2 -2
View File
@@ -7,12 +7,12 @@ This URL provides the most recent documentation and also applies to previous ver
functions is not removed; instead, it is marked as deprecated. functions is not removed; instead, it is marked as deprecated.
If you want to view the documentation for a specific tag or commit hash, you can generate it locally as follows (example If you want to view the documentation for a specific tag or commit hash, you can generate it locally as follows (example
using tag `v3.10.2`): using tag `v3.12.0`):
```shell ```shell
git clone https://github.com/nlohmann/json.git git clone https://github.com/nlohmann/json.git
cd json cd json
git checkout v3.10.2 git checkout v3.12.0
make install_venv serve -C docs/mkdocs make install_venv serve -C docs/mkdocs
``` ```
+11 -55
View File
@@ -1,48 +1,24 @@
SHELL=/usr/bin/env bash SHELL=/usr/bin/env bash
SED ?= $(shell which gsed 2>/dev/null || which sed) PYTHON=../mkdocs/venv/bin/python3
MKDOCS_PAGES=$(shell cd ../mkdocs/docs/ && find * -type f -name '*.md' | sort)
.PHONY: all .PHONY: all
all: JSON_for_Modern_C++.tgz all: JSON_for_Modern_C++.tgz
docSet.dsidx: docSet.sql # generate the search index (the docset target does this itself, this is
# generate index # only handy for inspecting the index)
sqlite3 docSet.dsidx <docSet.sql docSet.dsidx: generate_docset.py
$(PYTHON) generate_docset.py index docSet.dsidx
JSON_for_Modern_C++.docset: Info.plist docSet.dsidx # build the documentation and turn it into a self-contained docset
rm -fr JSON_for_Modern_C++.docset JSON_for_Modern_C++.tgz .PHONY: JSON_for_Modern_C++.docset
mkdir -p JSON_for_Modern_C++.docset/Contents/Resources/Documents/ JSON_for_Modern_C++.docset:
cp icon*.png JSON_for_Modern_C++.docset
cp Info.plist JSON_for_Modern_C++.docset/Contents
# build and copy documentation
$(MAKE) install_venv -C ../mkdocs $(MAKE) install_venv -C ../mkdocs
$(MAKE) build -C ../mkdocs $(MAKE) build -C ../mkdocs
cp -r ../mkdocs/site/* JSON_for_Modern_C++.docset/Contents/Resources/Documents $(PYTHON) generate_docset.py docset ../mkdocs/site .
# patch CSS to hide navigation items
echo -e "\n\nheader, footer, nav.md-tabs, nav.md-tabs--active, div.md-sidebar--primary, a.md-content__button { display: none; }" >> "$$(ls JSON_for_Modern_C++.docset/Contents/Resources/Documents/assets/stylesheets/main.*.min.css)"
# fix spacing
echo -e "\n\ndiv.md-sidebar div.md-sidebar--secondary, div.md-main__inner { top: 0; margin-top: 0 }" >> "$$(ls JSON_for_Modern_C++.docset/Contents/Resources/Documents/assets/stylesheets/main.*.min.css)"
# remove "JSON for Modern C++" from page titles (fallback)
find JSON_for_Modern_C++.docset/Contents/Resources/Documents -type f -exec $(SED) -i 's| - JSON for Modern C++</title>|</title>|' {} +
# replace page titles with name from index, if available
for page in $(MKDOCS_PAGES); do \
case "$$page" in \
*/index.md) path=$${page/\/index.md/} ;; \
*) path=$${page/.md/} ;; \
esac; \
title=$$(sqlite3 docSet.dsidx "SELECT name FROM searchIndex WHERE path='$$path/index.html'" | tr '\n' ',' | $(SED) -e 's/,/, /g' -e 's/, $$/\n/'); \
if [ "x$$title" != "x" ]; then \
$(SED) -i "s%<title>.*</title>%<title>$$title</title>%" "JSON_for_Modern_C++.docset/Contents/Resources/Documents/$$path/index.html"; \
fi \
done
# clean up
rm JSON_for_Modern_C++.docset/Contents/Resources/Documents/sitemap.*
# copy index
cp docSet.dsidx JSON_for_Modern_C++.docset/Contents/Resources/
.PHONY: JSON_for_Modern_C++.tgz
JSON_for_Modern_C++.tgz: JSON_for_Modern_C++.docset JSON_for_Modern_C++.tgz: JSON_for_Modern_C++.docset
tar --exclude='.DS_Store' -cvzf JSON_for_Modern_C++.tgz JSON_for_Modern_C++.docset $(PYTHON) generate_docset.py tgz .
# install docset for Zeal documentation browser (https://zealdocs.org/) # install docset for Zeal documentation browser (https://zealdocs.org/)
.PHONY: install_docset_zeal .PHONY: install_docset_zeal
@@ -52,26 +28,6 @@ install_docset_zeal: JSON_for_Modern_C++.docset
mkdir -p $$docset_root; \ mkdir -p $$docset_root; \
cp -r JSON_for_Modern_C++.docset $$docset_root/ cp -r JSON_for_Modern_C++.docset $$docset_root/
# both targets below compare the docset search index with the mkdocs page
# set. They share the same normalization (docs/foo/index.md and
# docs/foo.md both become foo/index.html, the URL mkdocs itself would
# give the page; the top-level index.md is excluded, as it is not part
# of the hand-curated docSet.sql) and use comm(1) on two sorted lists
# instead of running a sqlite3 query, or an O(n*m) nested shell loop,
# once per page.
DOCSET_INDEX_PATHS=$(shell sqlite3 docSet.dsidx "SELECT DISTINCT path FROM searchIndex" | sort)
DOCSET_PAGE_PATHS=$(shell echo '$(MKDOCS_PAGES)' | tr ' ' '\n' | grep -v '^index\.md$$' | $(SED) -E 's@/index\.md$$@/index.html@; s@\.md$$@/index.html@' | sort)
# list mkdocs pages missing from the docset index
.PHONY: list_missing_pages
list_missing_pages: docSet.dsidx
@comm -23 <(echo '$(DOCSET_PAGE_PATHS)' | tr ' ' '\n') <(echo '$(DOCSET_INDEX_PATHS)' | tr ' ' '\n')
# list paths in the docset index without a corresponding mkdocs page
.PHONY: list_removed_paths
list_removed_paths: docSet.dsidx
@comm -13 <(echo '$(DOCSET_PAGE_PATHS)' | tr ' ' '\n') <(echo '$(DOCSET_INDEX_PATHS)' | tr ' ' '\n')
.PHONY: clean .PHONY: clean
clean: clean:
rm -f docSet.dsidx rm -f docSet.dsidx
+3 -1
View File
@@ -4,7 +4,8 @@ The folder contains the required files to create a [docset](https://kapeli.com/d
documentation browsers like [Dash](https://kapeli.com/dash), [Velocity](https://velocity.silverlakesoftware.com), or documentation browsers like [Dash](https://kapeli.com/dash), [Velocity](https://velocity.silverlakesoftware.com), or
[Zeal](https://zealdocs.org). [Zeal](https://zealdocs.org).
The docset can be created with The docset (pages and search index) is generated by `generate_docset.py` from the mkdocs site and `mkdocs.yml`. It
can be created with
```sh ```sh
make JSON_for_Modern_C++.docset make JSON_for_Modern_C++.docset
@@ -12,6 +13,7 @@ make JSON_for_Modern_C++.docset
The generated folder `JSON_for_Modern_C++.docset` can then be opened in the documentation browser. `make all` builds a The generated folder `JSON_for_Modern_C++.docset` can then be opened in the documentation browser. `make all` builds a
`JSON_for_Modern_C++.tgz` archive instead, and `make install_docset_zeal` installs the docset for Zeal directly. `JSON_for_Modern_C++.tgz` archive instead, and `make install_docset_zeal` installs the docset for Zeal directly.
`make docSet.dsidx` builds only the search index.
A recent version is also part of the [Dash user contributions](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B). A recent version is also part of the [Dash user contributions](https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/JSON_for_Modern_C%2B%2B).
-289
View File
@@ -1,289 +0,0 @@
DROP TABLE IF EXISTS searchIndex;
CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);
CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path);
-- API
INSERT INTO searchIndex(name, type, path) VALUES ('adl_serializer', 'Class', 'api/adl_serializer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('adl_serializer::from_json', 'Function', 'api/adl_serializer/from_json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('adl_serializer::to_json', 'Function', 'api/adl_serializer/to_json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype', 'Class', 'api/byte_container_with_subtype/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::byte_container_with_subtype', 'Constructor', 'api/byte_container_with_subtype/byte_container_with_subtype/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::clear_subtype', 'Method', 'api/byte_container_with_subtype/clear_subtype/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::has_subtype', 'Method', 'api/byte_container_with_subtype/has_subtype/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::operator!=', 'Operator', 'api/byte_container_with_subtype/operator_ne/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::operator==', 'Operator', 'api/byte_container_with_subtype/operator_eq/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::set_subtype', 'Method', 'api/byte_container_with_subtype/set_subtype/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype::subtype', 'Method', 'api/byte_container_with_subtype/subtype/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json', 'Class', 'api/basic_json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('format_as', 'Function', 'api/basic_json/format_as/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::accept', 'Function', 'api/basic_json/accept/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::array', 'Function', 'api/basic_json/array/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::array_t', 'Type', 'api/basic_json/array_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::as_base_class', 'Method', 'api/basic_json/as_base_class/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::at', 'Method', 'api/basic_json/at/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::back', 'Method', 'api/basic_json/back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::basic_json', 'Constructor', 'api/basic_json/basic_json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::begin', 'Method', 'api/basic_json/begin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::binary', 'Function', 'api/basic_json/binary/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::binary_t', 'Type', 'api/basic_json/binary_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::boolean_t', 'Type', 'api/basic_json/boolean_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::cbegin', 'Method', 'api/basic_json/cbegin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::cbor_tag_handler_t', 'Enum', 'api/basic_json/cbor_tag_handler_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::cend', 'Method', 'api/basic_json/cend/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::clear', 'Method', 'api/basic_json/clear/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::contains', 'Method', 'api/basic_json/contains/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::count', 'Method', 'api/basic_json/count/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::crbegin', 'Method', 'api/basic_json/crbegin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::crend', 'Method', 'api/basic_json/crend/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::default_object_comparator_t', 'Type', 'api/basic_json/default_object_comparator_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::diff', 'Function', 'api/basic_json/diff/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::dump', 'Method', 'api/basic_json/dump/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::emplace', 'Method', 'api/basic_json/emplace/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::emplace_back', 'Method', 'api/basic_json/emplace_back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::empty', 'Method', 'api/basic_json/empty/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::end', 'Method', 'api/basic_json/end/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::end_pos', 'Method', 'api/basic_json/end_pos/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::erase', 'Method', 'api/basic_json/erase/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::error_handler_t', 'Enum', 'api/basic_json/error_handler_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::exception', 'Class', 'api/basic_json/exception/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::find', 'Method', 'api/basic_json/find/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::flatten', 'Method', 'api/basic_json/flatten/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_bjdata', 'Function', 'api/basic_json/from_bjdata/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_bson', 'Function', 'api/basic_json/from_bson/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_cbor', 'Function', 'api/basic_json/from_cbor/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_msgpack', 'Function', 'api/basic_json/from_msgpack/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_bon8', 'Function', 'api/basic_json/from_bon8/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::from_ubjson', 'Function', 'api/basic_json/from_ubjson/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::front', 'Method', 'api/basic_json/front/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get', 'Method', 'api/basic_json/get/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_allocator', 'Function', 'api/basic_json/get_allocator/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_binary', 'Method', 'api/basic_json/get_binary/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_ptr', 'Method', 'api/basic_json/get_ptr/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_ref', 'Method', 'api/basic_json/get_ref/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::get_to', 'Method', 'api/basic_json/get_to/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::input_format_t', 'Enum', 'api/basic_json/input_format_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::insert', 'Method', 'api/basic_json/insert/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::invalid_iterator', 'Class', 'api/basic_json/invalid_iterator/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_array', 'Method', 'api/basic_json/is_array/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_binary', 'Method', 'api/basic_json/is_binary/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_boolean', 'Method', 'api/basic_json/is_boolean/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_discarded', 'Method', 'api/basic_json/is_discarded/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_null', 'Method', 'api/basic_json/is_null/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number', 'Method', 'api/basic_json/is_number/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number_float', 'Method', 'api/basic_json/is_number_float/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number_integer', 'Method', 'api/basic_json/is_number_integer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_number_unsigned', 'Method', 'api/basic_json/is_number_unsigned/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_object', 'Method', 'api/basic_json/is_object/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_primitive', 'Method', 'api/basic_json/is_primitive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_string', 'Method', 'api/basic_json/is_string/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::is_structured', 'Method', 'api/basic_json/is_structured/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::items', 'Method', 'api/basic_json/items/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::json_base_class_t', 'Type', 'api/basic_json/json_base_class_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::json_serializer', 'Class', 'api/basic_json/json_serializer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::max_size', 'Method', 'api/basic_json/max_size/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::merge_patch', 'Method', 'api/basic_json/merge_patch/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::meta', 'Function', 'api/basic_json/meta/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::number_float_t', 'Type', 'api/basic_json/number_float_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::number_integer_t', 'Type', 'api/basic_json/number_integer_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::number_unsigned_t', 'Type', 'api/basic_json/number_unsigned_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::object', 'Function', 'api/basic_json/object/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::object_comparator_t', 'Type', 'api/basic_json/object_comparator_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::object_t', 'Type', 'api/basic_json/object_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator ValueType', 'Operator', 'api/basic_json/operator_ValueType/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator value_t', 'Operator', 'api/basic_json/operator_value_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator[]', 'Operator', 'api/basic_json/operator[]/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator=', 'Operator', 'api/basic_json/operator=/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator+=', 'Operator', 'api/basic_json/operator+=/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator==', 'Operator', 'api/basic_json/operator_eq/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator!=', 'Operator', 'api/basic_json/operator_ne/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator<', 'Operator', 'api/basic_json/operator_lt/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator<=', 'Operator', 'api/basic_json/operator_le/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator>', 'Operator', 'api/basic_json/operator_gt/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator>=', 'Operator', 'api/basic_json/operator_ge/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::operator<=>', 'Operator', 'api/basic_json/operator_spaceship/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::out_of_range', 'Class', 'api/basic_json/out_of_range/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::other_error', 'Class', 'api/basic_json/other_error/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parse', 'Function', 'api/basic_json/parse/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parse_error', 'Class', 'api/basic_json/parse_error/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parse_event_t', 'Enum', 'api/basic_json/parse_event_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::parser_callback_t', 'Type', 'api/basic_json/parser_callback_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::patch', 'Method', 'api/basic_json/patch/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::patch_inplace', 'Method', 'api/basic_json/patch_inplace/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::push_back', 'Method', 'api/basic_json/push_back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::rbegin', 'Method', 'api/basic_json/rbegin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::rend', 'Method', 'api/basic_json/rend/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::sax_parse', 'Function', 'api/basic_json/sax_parse/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::size', 'Method', 'api/basic_json/size/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::start_pos', 'Method', 'api/basic_json/start_pos/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::string_t', 'Type', 'api/basic_json/string_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::swap', 'Method', 'api/basic_json/swap/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::type', 'Method', 'api/basic_json/type/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::type_error', 'Class', 'api/basic_json/type_error/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::type_name', 'Method', 'api/basic_json/type_name/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::unflatten', 'Method', 'api/basic_json/unflatten/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::update', 'Method', 'api/basic_json/update/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_bjdata', 'Function', 'api/basic_json/to_bjdata/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_bson', 'Function', 'api/basic_json/to_bson/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_cbor', 'Function', 'api/basic_json/to_cbor/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_msgpack', 'Function', 'api/basic_json/to_msgpack/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_bon8', 'Function', 'api/basic_json/to_bon8/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_string', 'Method', 'api/basic_json/to_string/index.html');
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 ('json', 'Class', 'api/json/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');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::front', 'Method', 'api/json_pointer/front/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::json_pointer', 'Constructor', 'api/json_pointer/json_pointer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator==', 'Operator', 'api/json_pointer/operator_eq/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator!=', 'Operator', 'api/json_pointer/operator_ne/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator/', 'Operator', 'api/json_pointer/operator_slash/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator/=', 'Operator', 'api/json_pointer/operator_slasheq/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator string_t', 'Operator', 'api/json_pointer/operator_string_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::operator<=>', 'Operator', 'api/json_pointer/operator_spaceship/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::parent_pointer', 'Method', 'api/json_pointer/parent_pointer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::pop_back', 'Method', 'api/json_pointer/pop_back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::pop_front', 'Method', 'api/json_pointer/pop_front/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::push_back', 'Method', 'api/json_pointer/push_back/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::push_front', 'Method', 'api/json_pointer/push_front/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::string_t', 'Type', 'api/json_pointer/string_t/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::to_string', 'Method', 'api/json_pointer/to_string/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax', 'Class', 'api/json_sax/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::binary', 'Method', 'api/json_sax/binary/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::boolean', 'Method', 'api/json_sax/boolean/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::end_array', 'Method', 'api/json_sax/end_array/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::end_object', 'Method', 'api/json_sax/end_object/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::key', 'Method', 'api/json_sax/key/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::null', 'Method', 'api/json_sax/null/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::number_float', 'Method', 'api/json_sax/number_float/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::number_integer', 'Method', 'api/json_sax/number_integer/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::number_unsigned', 'Method', 'api/json_sax/number_unsigned/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::parse_error', 'Method', 'api/json_sax/parse_error/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::start_array', 'Method', 'api/json_sax/start_array/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::start_object', 'Method', 'api/json_sax/start_object/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('json_sax::string', 'Method', 'api/json_sax/string/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('operator""_json', 'Literal', 'api/operator_literal_json/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('operator""_json_pointer', 'Literal', 'api/operator_literal_json_pointer/index.html');
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_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');
INSERT INTO searchIndex(name, type, path) VALUES ('std::swap<basic_json>', 'Function', 'api/basic_json/std_swap/index.html');
-- Features
INSERT INTO searchIndex(name, type, path) VALUES ('Arbitrary Type Conversions', 'Guide', 'features/arbitrary_types/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats', 'Guide', 'features/binary_formats/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: BJData', 'Guide', 'features/binary_formats/bjdata/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: BSON', 'Guide', 'features/binary_formats/bson/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: CBOR', 'Guide', 'features/binary_formats/cbor/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: MessagePack', 'Guide', 'features/binary_formats/messagepack/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: BON8', 'Guide', 'features/binary_formats/bon8/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Formats: UBJSON', 'Guide', 'features/binary_formats/ubjson/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Binary Values', 'Guide', 'features/binary_values/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Comments', 'Guide', 'features/comments/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Element Access', 'Guide', 'features/element_access/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Access with default value: value', 'Guide', 'features/element_access/default_value/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Checked access: at', 'Guide', 'features/element_access/checked_access/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Element Access: Unchecked access: operator[]', 'Guide', 'features/element_access/unchecked_access/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Exceptions', 'Guide', 'home/exceptions/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Migration Guide', 'Guide', 'integration/migration_guide/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: CMake', 'Guide', 'integration/cmake/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Header only', 'Guide', 'integration/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Package Managers', 'Guide', 'integration/package_managers/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Integration: Pkg-config', 'Guide', 'integration/pkg-config/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Iterators', 'Guide', 'features/iterators/index.html');
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 ('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');
INSERT INTO searchIndex(name, type, path) VALUES ('Object Order', 'Guide', 'features/object_order/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Performance', 'Guide', 'features/performance/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Parsing', 'Guide', 'features/parsing/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: JSON Lines', 'Guide', 'features/parsing/json_lines/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: Parser Callbacks', 'Guide', 'features/parsing/parser_callbacks/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: Parsing and Exceptions', 'Guide', 'features/parsing/parse_exceptions/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: SAX Interface', 'Guide', 'features/parsing/sax_interface/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Parsing: Untrusted Input', 'Guide', 'features/parsing/untrusted_input/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Runtime Assertions', 'Guide', 'features/assertions/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Specializing enum conversion', 'Guide', 'features/enum_conversion/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('Supported Macros', 'Guide', 'features/macros/index.html');
-- Macros
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');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_TUPLE_REFERENCE_CONVERSION', 'Macro', 'api/macros/json_disable_tuple_reference_conversion/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_11', 'Macro', 'api/macros/json_has_cpp_11/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_14', 'Macro', 'api/macros/json_has_cpp_11/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_17', 'Macro', 'api/macros/json_has_cpp_11/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_20', 'Macro', 'api/macros/json_has_cpp_11/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_23', 'Macro', 'api/macros/json_has_cpp_11/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_26', 'Macro', 'api/macros/json_has_cpp_11/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_EXPERIMENTAL_FILESYSTEM', 'Macro', 'api/macros/json_has_filesystem/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_FILESYSTEM', 'Macro', 'api/macros/json_has_filesystem/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_RANGES', 'Macro', 'api/macros/json_has_ranges/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_STATIC_RTTI', 'Macro', 'api/macros/json_has_static_rtti/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_STD_FORMAT', 'Macro', 'api/macros/json_has_std_format/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_THREE_WAY_COMPARISON', 'Macro', 'api/macros/json_has_three_way_comparison/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_NOEXCEPTION', 'Macro', 'api/macros/json_noexception/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_NO_AUTOMATIC_UDLS', 'Macro', 'api/macros/json_no_automatic_udls/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_NO_IO', 'Macro', 'api/macros/json_no_io/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_NO_THREAD_LOCAL', 'Macro', 'api/macros/json_no_thread_local/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_PRECISE_STREAM_POSITION', 'Macro', 'api/macros/json_precise_stream_position/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_SKIP_LIBRARY_VERSION_CHECK', 'Macro', 'api/macros/json_skip_library_version_check/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_SKIP_UNSUPPORTED_COMPILER_CHECK', 'Macro', 'api/macros/json_skip_unsupported_compiler_check/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_STRICT_BINARY_UTF8', 'Macro', 'api/macros/json_strict_binary_utf8/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_STRICT_NUL_HANDLING', 'Macro', 'api/macros/json_strict_nul_handling/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_THROW_USER', 'Macro', 'api/macros/json_throw_user/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_TRY_USER', 'Macro', 'api/macros/json_throw_user/index.html');
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');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT', 'Macro', 'api/macros/nlohmann_define_derived_type/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_type_intrusive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE', 'Macro', 'api/macros/nlohmann_define_type_intrusive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT', 'Macro', 'api/macros/nlohmann_define_type_intrusive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE', 'Macro', 'api/macros/nlohmann_define_type_non_intrusive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE', 'Macro', 'api/macros/nlohmann_define_type_non_intrusive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT', 'Macro', 'api/macros/nlohmann_define_type_non_intrusive/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES', 'Macro', 'api/macros/nlohmann_define_type_with_names/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE', 'Macro', 'api/macros/nlohmann_json_namespace/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_BEGIN', 'Macro', 'api/macros/nlohmann_json_namespace_begin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_END', 'Macro', 'api/macros/nlohmann_json_namespace_begin/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_NAMESPACE_NO_VERSION', 'Macro', 'api/macros/nlohmann_json_namespace_no_version/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM', 'Macro', 'api/macros/nlohmann_json_serialize_enum/index.html');
INSERT INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM_STRICT', 'Macro', 'api/macros/nlohmann_json_serialize_enum_strict/index.html');
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');
+532
View File
@@ -0,0 +1,532 @@
#!/usr/bin/env python3
"""Generate the Dash docset search index from the mkdocs sources."""
import argparse
import glob
import hashlib
import html
import os
import re
import shutil
import sqlite3
import sys
import tarfile
import urllib.parse
import urllib.request
import yaml
HERE = os.path.dirname(os.path.abspath(__file__))
MKDOCS_YML = os.path.join(HERE, '..', 'mkdocs', 'mkdocs.yml')
PAGES = os.path.join(HERE, '..', 'mkdocs', 'docs')
# api pages whose (name, type) cannot be derived by the heuristics
OVERRIDES = {
}
DOCSET = 'JSON_for_Modern_C++.docset'
TITLE_SUFFIX = ' - JSON for Modern C++</title>'
# CSS rules appended to the stylesheet: hide navigation items and fix spacing
# hide the navigation (the documentation browser has its own); Material's class selectors would win over element
# selectors, hence the classes and !important
CSS_PATCH = (
'\n\n.md-header, .md-footer, .md-tabs, .md-sidebar--primary, .md-content__button { display: none !important; }'
'\n\n.md-sidebar--secondary, .md-main__inner { top: 0 !important; margin-top: 0 !important; }'
)
USER_AGENT = ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/124.0 Safari/537.36')
CONTENT_TYPE_EXT = {'image/svg+xml': '.svg', 'image/png': '.png', 'image/jpeg': '.jpg',
'image/gif': '.gif', 'image/webp': '.webp'}
# remote loads that are allowed to remain (URL -> reason)
ALLOWED_REMOTE = {
# Material only loads this polyfill if the browser has no ResizeObserver
'https://unpkg.com/resize-observer-polyfill': 'fallback for browsers without ResizeObserver',
}
problems = []
def problem(page, reason) -> None:
"""Record a problem; all problems are reported at the end."""
problems.append(f'generate_docset.py: {page}: {reason}')
class Loader(yaml.SafeLoader):
"""YAML loader that tolerates the custom tags used in mkdocs.yml."""
Loader.add_multi_constructor('', lambda loader, suffix, node: None)
def walk_nav(items, groups=()):
"""Yield (group titles, nav title or None, md path) for all nav leaves."""
for item in items:
if isinstance(item, str):
yield list(groups), None, item
elif isinstance(item, dict):
for title, value in item.items():
if isinstance(value, list):
yield from walk_nav(value, groups + (str(title),))
else:
yield list(groups), str(title), value
def page_path(md_path) -> str:
"""Map a markdown path to the HTML path of the rendered page."""
if md_path.endswith('/index.md'):
return md_path[:-len('index.md')] + 'index.html'
return md_path[:-len('.md')] + '/index.html'
def read_page(md_path) -> str:
"""Read a page (resolving a snippet include), return '' if it does not exist."""
try:
with open(os.path.join(PAGES, md_path), encoding='utf-8') as f:
text = f.read()
m = re.match(r'--8<-- "(.+)"\s*$', text)
if m:
with open(os.path.join(PAGES, m.group(1)), encoding='utf-8') as f:
text = f.read()
return text
except OSError:
return ''
def clean(text) -> str:
"""Strip tags and entities from a heading and normalize whitespace."""
text = text.replace('\\>', '\x00') # escaped '>' is not the end of a tag
text = html.unescape(re.sub(r'</?[a-zA-Z][^>]*>', '', text)).replace('\x00', '>')
return re.sub(r'\s+', ' ', text).strip()
def strip_fences(text) -> str:
"""Remove fenced code blocks (their lines may start with '# ')."""
return re.sub(r'^(```|~~~).*?^\1[^\n]*$', '', text, flags=re.M | re.S)
def get_h1(text):
"""Return the cleaned first H1 of a page or None."""
body = strip_fences(text)
m = re.search(r'^# (.+)$', body, flags=re.M)
if m:
return clean(m.group(1))
m = re.search(r'<h1>(.*?)</h1>', body, flags=re.S)
return clean(m.group(1)) if m else None
def split_top_level(text, seps=','):
"""Split at separators that are not nested in <>, () or []."""
parts, depth, current = [], 0, ''
for c in text:
if c in '<([':
depth += 1
elif c in '>)]':
depth -= 1
if c in seps and depth <= 0:
parts.append(current)
current = ''
else:
current += c
parts.append(current)
return [p.strip() for p in parts if p.strip()]
OPERATOR_SYMBOLS = ('<=>', '<<', '>>', '<=', '>=', '<', '>')
def api_names(h1) -> list:
"""Derive the entry names from the H1 of an api page."""
# hide the angle brackets of operators from the nesting detection
for i, sym in enumerate(OPERATOR_SYMBOLS):
h1 = h1.replace('operator' + sym, f'operator\x01{i}\x01')
names = []
for part in split_top_level(h1):
name = part.replace('\\', '').replace('nlohmann::', '')
name = re.sub(r'\x01(\d)\x01', lambda m: OPERATOR_SYMBOLS[int(m.group(1))], name)
# drop qualifiers like "operator<<(basic_json)", but keep "operator()"
if not name.endswith('operator()'):
name = re.sub(r'(?<=\w|[<>=!+\-*/\[\]])\([^()]*\)$', '', name)
if name not in names:
names.append(name)
return names
def first_cpp_block(text):
"""Return the first ```cpp block following the H1."""
m = re.search(r'^# .*?^```cpp\n(.*?)^```', text, flags=re.M | re.S)
return m.group(1) if m else None
def api_type(name, decl):
"""Determine the Dash entry type from name and declaration."""
parts = name.split('::')
last = parts[-1]
if name.startswith('operator""'):
return 'Literal'
if last.startswith('operator'):
return 'Operator'
if decl is None:
return None
if re.search(r'\benum\b', decl):
return 'Enum'
if re.search(r'^\s*(template\s*<.*>\s*)?(class|struct)\s+\w+\s*(final\b|[:{;<]|$)', decl, flags=re.M):
return 'Class'
if re.search(r'\busing\s+\w+\s*=', decl) or 'typedef' in decl:
return 'Type'
if len(parts) > 1 and last == parts[-2]:
return 'Constructor'
if last.startswith('~'):
return 'Method'
if re.search(r'\bstatic\b', decl) or len(parts) == 1 or parts[0] == 'std':
return 'Function'
return 'Method'
def macro_names(h1) -> list:
"""Split the H1 of a macro page into macro names."""
return [n.strip() for n in re.split(r'[,/]', h1) if n.strip()]
def api_entries(md_path):
"""Return the (name, type) pairs of an api page."""
if md_path in OVERRIDES:
return OVERRIDES[md_path]
if md_path == 'api/macros/index.md':
return [('Macros', 'Macro')]
text = read_page(md_path)
h1 = get_h1(text)
if not h1:
problem(md_path, 'no H1 found')
return []
if md_path.startswith('api/macros/'):
return [(n, 'Macro') for n in macro_names(h1)]
names = api_names(h1)
if not names:
problem(md_path, 'no names found')
return []
decl = first_cpp_block(text)
result = []
for name in names:
kind = api_type(name, decl)
if kind is None:
problem(md_path, f'no type determinable for {name}')
else:
result.append((name, kind))
return result
def guide_entries(nav):
"""Yield (name, type, md path) for all non-api nav pages."""
for groups, title, md_path in walk_nav(nav):
if md_path.startswith('api/') or md_path == 'index.md':
continue
if not md_path.endswith('.md'):
continue
groups = groups[1:] # drop the top-level tab
if title is None:
title = get_h1(read_page(md_path))
if not title:
problem(md_path, 'no title found')
continue
# "Parsing: Parsing Untrusted Input" -> "Parsing: Untrusted Input"
if groups and title.startswith(groups[-1] + ' ') and title[len(groups[-1]) + 1:][:1].isupper():
title = title[len(groups[-1]) + 1:]
if md_path.endswith('/index.md') and groups and title == groups[-1]:
name = ': '.join(groups)
else:
name = ': '.join(groups + [title])
yield name, 'Guide', md_path
def build_entries() -> list:
"""Return the sorted list of (name, type, path) index entries."""
nav = load_mkdocs_yml()['nav']
entries = set()
for name, kind, md_path in guide_entries(nav):
entries.add((name, kind, page_path(md_path)))
api_root = os.path.join(PAGES, 'api')
on_disk = set()
for root, _, files in os.walk(api_root):
for file in files:
if file.endswith('.md'):
rel = os.path.relpath(os.path.join(root, file), PAGES)
on_disk.add(rel.replace(os.sep, '/'))
for _, _, md_path in walk_nav(nav):
if md_path.startswith('api/') and md_path not in on_disk:
problem(md_path, 'listed in nav but missing on disk')
for md_path in sorted(on_disk):
for name, kind in api_entries(md_path):
entries.add((name, kind, page_path(md_path)))
return sorted(entries)
def write_index(entries, out) -> None:
"""Write the entries into a SQLite search index."""
if os.path.exists(out):
os.remove(out)
con = sqlite3.connect(out)
con.execute('CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT)')
con.execute('CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path)')
con.executemany('INSERT INTO searchIndex(name, type, path) VALUES (?, ?, ?)', entries)
con.commit()
con.close()
def html_files(root):
"""Yield all HTML files below root."""
for base, _, files in os.walk(root):
for file in files:
if file.endswith('.html'):
yield os.path.join(base, file)
def read(path) -> str:
with open(path, encoding='utf-8') as f:
return f.read()
def write(path, text) -> None:
with open(path, 'w', encoding='utf-8') as f:
f.write(text)
def remove_source_widget(docs) -> None:
"""Drop data-md-component=source so Material does not query api.github.com for the stars and version."""
pattern = re.compile(r'\sdata-md-component=(?:"source"|source\b)')
for path in html_files(docs):
text = read(path)
new = pattern.sub('', text)
if new != text:
write(path, new)
def patch_titles(docs, entries) -> None:
"""Strip the site name from all titles; use the index names where available."""
names = {}
for name, _, path in entries:
names.setdefault(path, []).append(name)
for file in html_files(docs):
rel = os.path.relpath(file, docs).replace(os.sep, '/')
text = read(file).replace(TITLE_SUFFIX, '</title>')
if rel in names:
title = html.escape(', '.join(names[rel]), quote=False)
text = re.sub(r'<title>.*?</title>', lambda _: f'<title>{title}</title>', text, count=1, flags=re.S)
write(file, text)
IMG_RE = re.compile(r'<img\b[^>]*>', re.I)
ATTR_RE = r'''(?:{0})\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+))'''
def attr(tag, name):
"""Return the value of an attribute in a tag or None."""
m = re.search(r'(?<![\w-])' + ATTR_RE.format(name), tag, flags=re.I)
return next(g for g in m.groups() if g is not None) if m else None
def is_remote(url) -> bool:
return re.match(r'(https?:)?//', url.strip(), flags=re.I) is not None
def download(url, docs) -> str:
"""Download url into assets/external and return the path relative to docs."""
u = urllib.parse.urlparse(url if not url.startswith('//') else 'https:' + url)
if u.scheme.lower() not in ('http', 'https'):
raise ValueError(f'not an http(s) URL: {url}')
req = urllib.request.Request(u.geturl(), headers={'User-Agent': USER_AGENT})
# (the scheme is checked above)
with urllib.request.urlopen(req, timeout=20) as r: # nosec B310
data = r.read()
ctype = r.headers.get_content_type()
path = urllib.parse.unquote(u.path).lstrip('/')
ext = os.path.splitext(path)[1]
if u.query or not ext or path.endswith('/'):
digest = hashlib.sha1(url.encode(), usedforsecurity=False).hexdigest()[:12]
path = os.path.join(os.path.dirname(path), digest + CONTENT_TYPE_EXT.get(ctype, ext or '.bin'))
rel = os.path.normpath(os.path.join('assets', 'external', u.hostname, path))
out = os.path.join(docs, rel)
os.makedirs(os.path.dirname(out), exist_ok=True)
with open(out, 'wb') as f:
f.write(data)
return rel.replace(os.sep, '/')
def localize_images(docs) -> None:
"""Download remote images and rewrite their src; drop them on failure."""
cache = {}
for file in html_files(docs):
text = read(file)
def repl(m):
tag = m.group(0)
src = attr(tag, 'src')
if src is None or not is_remote(src):
return tag
if src not in cache:
try:
cache[src] = download(src, docs)
except Exception as e: # noqa: BLE001
print(f'generate_docset.py: warning: cannot download {src}: {e}', file=sys.stderr)
cache[src] = None
if cache[src] is None:
return attr(tag, 'alt') or ''
local = os.path.relpath(os.path.join(docs, cache[src]), os.path.dirname(file))
local = local.replace(os.sep, '/')
return re.sub(ATTR_RE.format('src'), lambda _: f'src="{local}"', tag, count=1, flags=re.I)
new = IMG_RE.sub(repl, text)
if new != text:
write(file, new)
def load_mkdocs_yml() -> dict:
"""Load mkdocs.yml, ignoring tags like !ENV and !!python/name."""
with open(MKDOCS_YML, encoding='utf-8') as f:
# (Loader is a yaml.SafeLoader)
return yaml.load(f, Loader=Loader) # nosec B506
def localize_site_urls(docs, site_url) -> None:
"""Load assets that the theme's JavaScript references by absolute site URL from the docset.
The privacy plugin rewrites the mermaid loader to "<site_url>assets/external/unpkg.com/mermaid@11/...", so the
docset would fetch mermaid from the live site. __md_scope is the site root that Material defines in every page.
"""
pattern = re.compile(r'"' + re.escape(site_url) + r'(assets/[^"]*)"')
for base, _, files in os.walk(docs):
for file in (f for f in files if f.endswith('.js')):
path = os.path.join(base, file)
text = read(path)
new = pattern.sub(r'new URL("\1",__md_scope).href', text)
if new != text:
write(path, new)
def remote_loads(docs, site_url) -> list:
"""Return 'file: url' strings for resources that would be loaded remotely."""
found = []
cdn = re.compile(r'https://(?:unpkg\.com|cdn\.jsdelivr\.net|cdnjs\.cloudflare\.com|'
r'fonts\.googleapis\.com|fonts\.gstatic\.com)/[^\s"\'`)\\]*')
css_url = re.compile(r'url\(\s*["\']?((?:https?:)?//[^)"\']+)', re.I)
css_import = re.compile(r'@import\s+(?:url\(\s*)?["\']?((?:https?:)?//[^)"\'; ]+)', re.I)
for base, _, files in os.walk(docs):
for file in files:
path = os.path.join(base, file)
rel = os.path.relpath(path, docs)
urls = []
if file.endswith('.html'):
text = read(path)
for m in re.finditer(r'<[a-zA-Z][^>]*>', text):
tag = m.group(0)
for name in ('src', 'poster'):
v = attr(tag, name)
if v and is_remote(v):
urls.append(v)
v = attr(tag, 'srcset')
if v:
urls += [c.split()[0] for c in v.split(',') if c.strip() and is_remote(c.strip())]
if re.match(r'<link\b', tag, flags=re.I):
rel_attr = (attr(tag, 'rel') or '').lower()
v = attr(tag, 'href')
if v and is_remote(v) and re.search(r'stylesheet|icon|preload|modulepreload|manifest', rel_attr):
urls.append(v)
urls += css_url.findall(text) + css_import.findall(text)
elif file.endswith('.css'):
text = read(path)
urls += css_url.findall(text) + css_import.findall(text)
elif file.endswith('.js'):
text = read(path)
urls += cdn.findall(text)
urls += re.findall(re.escape(site_url) + r'assets/[^\s"\'`)\\]*', text)
found += [f'{rel}: {u}' for u in urls if u not in ALLOWED_REMOTE]
return found
def make_docset(site, out_dir) -> int:
entries = build_entries()
if problems:
print('\n'.join(problems), file=sys.stderr)
return 1
docset = os.path.join(out_dir, DOCSET)
docs = os.path.join(docset, 'Contents', 'Resources', 'Documents')
if os.path.exists(docset):
shutil.rmtree(docset)
shutil.copytree(site, docs)
for icon in ('icon.png', 'icon@2x.png'):
shutil.copy(os.path.join(HERE, icon), docset)
shutil.copy(os.path.join(HERE, 'Info.plist'), os.path.join(docset, 'Contents'))
write_index(entries, os.path.join(docset, 'Contents', 'Resources', 'docSet.dsidx'))
# patch CSS to hide navigation items and fix spacing
css = glob.glob(os.path.join(docs, 'assets', 'stylesheets', 'main.*.min.css'))
if len(css) != 1:
print(f'generate_docset.py: expected exactly one main.*.min.css, found {len(css)}', file=sys.stderr)
return 1
with open(css[0], 'a', encoding='utf-8') as f:
f.write(CSS_PATCH)
patch_titles(docs, entries)
remove_source_widget(docs)
for sitemap in glob.glob(os.path.join(docs, 'sitemap.*')):
os.remove(sitemap)
# make the docset self-contained
site_url = load_mkdocs_yml()['site_url']
localize_images(docs)
localize_site_urls(docs, site_url)
remote = remote_loads(docs, site_url)
if remote:
print('generate_docset.py: remote resources remain in the docset:', file=sys.stderr)
print('\n'.join(' ' + r for r in remote), file=sys.stderr)
return 1
return 0
def make_tgz(out_dir) -> int:
docset = os.path.join(out_dir, DOCSET)
if not os.path.isdir(docset):
print(f'generate_docset.py: {docset} does not exist', file=sys.stderr)
return 1
with tarfile.open(os.path.join(out_dir, 'JSON_for_Modern_C++.tgz'), 'w:gz') as tar:
tar.add(docset, arcname=DOCSET, filter=lambda i: None if os.path.basename(i.name) == '.DS_Store' else i)
return 0
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
sub = parser.add_subparsers(dest='command', required=True)
sub.add_parser('list', help='print the index entries as TSV')
p = sub.add_parser('index', help='write the SQLite search index')
p.add_argument('out')
p = sub.add_parser('docset', help='build the docset from a built mkdocs site')
p.add_argument('site_dir')
p.add_argument('out_dir')
p = sub.add_parser('tgz', help='pack the docset into a tarball')
p.add_argument('out_dir')
args = parser.parse_args()
if args.command == 'docset':
return make_docset(args.site_dir, args.out_dir)
if args.command == 'tgz':
return make_tgz(args.out_dir)
entries = build_entries()
if problems:
print('\n'.join(problems), file=sys.stderr)
return 1
if args.command == 'list':
for entry in entries:
print('\t'.join(entry))
elif args.command == 'index':
write_index(entries, args.out)
return 0
if __name__ == '__main__':
sys.exit(main())
+1
View File
@@ -17,6 +17,7 @@ build: style_check
style_check: style_check:
@cd docs ; ../venv/bin/python3 ../scripts/check_structure.py @cd docs ; ../venv/bin/python3 ../scripts/check_structure.py
@venv/bin/python3 ../docset/generate_docset.py list > /dev/null
# check that all Mermaid diagrams parse (needs Node.js) # check that all Mermaid diagrams parse (needs Node.js)
# This target is used in the CI (ci_test_documentation_mermaid). # This target is used in the CI (ci_test_documentation_mermaid).
+4 -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) - documentation on [checked access](../../features/element_access/checked_access.md)
- [`operator[]`](operator%5B%5D.md) for unchecked access by reference - [`operator[]`](operator%5B%5D.md) for unchecked access by reference
- [`value`](value.md) for access with default value - [`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 ## Version history
@@ -241,4 +242,6 @@ Strong exception safety: if an exception occurs, the original value stays intact
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as 3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
already supported by [`operator[]`](operator[].md), [`value`](value.md), [`find`](find.md), and other lookup already supported by [`operator[]`](operator[].md), [`value`](value.md), [`find`](find.md), and other lookup
functions. functions.
4. Added in version 2.0.0. 4. Added in version 2.0.0. Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not
a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones.
+1
View File
@@ -58,6 +58,7 @@ Constant.
## See also ## See also
- [front](front.md) to access the first element - [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 ## Version history
+2
View File
@@ -44,6 +44,8 @@ Constant.
- [rbegin](rbegin.md) returns a reverse iterator to the last element - [rbegin](rbegin.md) returns a reverse iterator to the last element
- [items](items.md) returns an iteration proxy to access keys and values during range-based for loops - [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 - [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 ## Version history
@@ -42,6 +42,7 @@ Constant.
- [cend](cend.md) returns a const iterator to one past the last element - [cend](cend.md) returns a const iterator to one past the last element
- [crbegin](crbegin.md) returns a const reverse iterator to the last element - [crbegin](crbegin.md) returns a const reverse iterator to the last element
- [Iterators](../../features/iterators.md) - the article on iterators - [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 ## Version history
+1
View File
@@ -42,6 +42,7 @@ Constant.
- [cbegin](cbegin.md) returns a const iterator to the first element - [cbegin](cbegin.md) returns a const iterator to the first element
- [crend](crend.md) returns a const reverse iterator to one before the first element - [crend](crend.md) returns a const reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators - [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 ## Version history
@@ -10,6 +10,10 @@ bool contains(KeyType&& key) const;
// (3) // (3)
bool contains(const json_pointer& ptr) const; bool contains(const json_pointer& ptr) const;
// (4)
template<typename T>
bool contains(T) const = delete;
``` ```
1. Check whether an element exists in a JSON object with a key equivalent to `key`. If the element is not found or the 1. Check whether an element exists in a JSON object with a key equivalent to `key`. If the element is not found or the
@@ -17,6 +21,9 @@ bool contains(const json_pointer& ptr) const;
2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and 2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and
`#!cpp typename object_comparator_t::is_transparent` denotes a type. `#!cpp typename object_comparator_t::is_transparent` denotes a type.
3. Check whether the given JSON pointer `ptr` can be resolved in the current JSON value. 3. Check whether the given JSON pointer `ptr` can be resolved in the current JSON value.
4. Deleted: this overload is only available if `T` is an integral type and is declared as deleted, so that a call with
an integer `key` (for example, `#!cpp j.contains(0)`) fails to compile. Otherwise, the integer literal `0` would convert to
a null `#!cpp const char*` and, from there, to the key type, causing undefined behavior at runtime.
## Template parameters ## Template parameters
@@ -39,6 +46,7 @@ bool contains(const json_pointer& ptr) const;
is not an object, `#!cpp false` is returned. is not an object, `#!cpp false` is returned.
2. See 1. 2. See 1.
3. `#!cpp true` if the JSON pointer can be resolved to a stored value, `#!cpp false` otherwise. 3. `#!cpp true` if the JSON pointer can be resolved to a stored value, `#!cpp false` otherwise.
4. Deleted; a call with an integral argument does not compile.
## Exception safety ## Exception safety
@@ -49,6 +57,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
1. The function does not throw exceptions. 1. The function does not throw exceptions.
2. The function does not throw exceptions. 2. The function does not throw exceptions.
3. The function does not throw exceptions. 3. The function does not throw exceptions.
4. Deleted; a call with an integral argument does not compile.
## Complexity ## Complexity
@@ -127,6 +136,7 @@ Logarithmic in the size of the JSON object.
- [find](find.md) find a value in an object - [find](find.md) find a value in an object
- [count](count.md) returns the number of occurrences of a key - [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 ## Version history
+8
View File
@@ -7,12 +7,19 @@ size_type count(const typename object_t::key_type& key) const;
// (2) // (2)
template<typename KeyType> template<typename KeyType>
size_type count(KeyType&& key) const; size_type count(KeyType&& key) const;
// (3)
template<typename T>
size_type count(T) const = delete;
``` ```
1. Returns the number of elements with key `key`. If `ObjectType` is the default `std::map` type, the return value will 1. Returns the number of elements with key `key`. If `ObjectType` is the default `std::map` type, the return value will
always be `0` (`key` was not found) or `1` (`key` was found). always be `0` (`key` was not found) or `1` (`key` was found).
2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and 2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and
`#!cpp typename object_comparator_t::is_transparent` denotes a type. `#!cpp typename object_comparator_t::is_transparent` denotes a type.
3. Deleted: this overload is only available if `T` is an integral type and is declared as deleted, so that a call with
an integer `key` (for example, `#!cpp j.count(0)`) fails to compile. Otherwise, the integer literal `0` would convert to
a null `#!cpp const char*` and, from there, to the key type, causing undefined behavior at runtime.
## Template parameters ## Template parameters
@@ -80,6 +87,7 @@ Logarithmic in the size of the JSON object.
- [find](find.md) find a value in an object - [find](find.md) find a value in an object
- [contains](contains.md) checks whether a key exists - [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 ## Version history
+7
View File
@@ -62,6 +62,9 @@ Linear.
## Notes ## 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: Binary values are serialized as an object containing two keys:
- "bytes": an array of bytes as integers - "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 - [to_string](to_string.md) returns a string representation of a JSON value
- [operator<<](../operator_ltlt.md) serialize to stream - [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 - [Serialization](../../features/serialization.md) - the serialization article
## Version history ## Version history
@@ -97,3 +102,5 @@ Binary values are serialized as an object containing two keys:
- Error handlers added in version 3.4.0. - Error handlers added in version 3.4.0.
- Serialization of binary values added in version 3.8.0. - Serialization of binary values added in version 3.8.0.
- Error handler `keep` added in version 3.13.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 - [size](size.md) returns the number of elements
- [clear](clear.md) clears the content and resets the value to the default value - [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 ## Version history
+1
View File
@@ -43,6 +43,7 @@ Constant.
- [cend](cend.md) returns a const iterator to one past the last element - [cend](cend.md) returns a const iterator to one past the last element
- [rend](rend.md) returns a reverse iterator to one before the first element - [rend](rend.md) returns a reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators - [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 ## Version history
@@ -37,8 +37,8 @@ ignore
: ignore invalid UTF-8 sequences; all valid bytes are copied to the output unchanged, and invalid bytes are dropped : ignore invalid UTF-8 sequences; all valid bytes are copied to the output unchanged, and invalid bytes are dropped
keep keep
: keep invalid UTF-8 sequences unchanged; only meaningful for the binary formats mentioned above, since [`dump`] : keep invalid UTF-8 sequences unchanged; only meaningful for the binary formats mentioned above, since
(dump.md) itself must produce text, and `keep` there writes the ill-formed bytes to the output as is, so the [`dump`](dump.md) itself must produce text, and `keep` there writes the ill-formed bytes to the output as is, so the
result is then not valid UTF-8 (but still equals the input bytes exactly, including around any well-formed result is then not valid UTF-8 (but still equals the input bytes exactly, including around any well-formed
characters, which are still escaped as usual) characters, which are still escaped as usual)
+10
View File
@@ -10,12 +10,21 @@ template<typename KeyType>
iterator find(KeyType&& key); iterator find(KeyType&& key);
template<typename KeyType> template<typename KeyType>
const_iterator find(KeyType&& key) const; const_iterator find(KeyType&& key) const;
// (3)
template<typename T>
iterator find(T) = delete;
template<typename T>
const_iterator find(T) const = delete;
``` ```
1. Finds an element in a JSON object with a key equivalent to `key`. If the element is not found or the 1. Finds an element in a JSON object with a key equivalent to `key`. If the element is not found or the
JSON value is not an object, `end()` is returned. JSON value is not an object, `end()` is returned.
2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and 2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and
`#!cpp typename object_comparator_t::is_transparent` denotes a type. `#!cpp typename object_comparator_t::is_transparent` denotes a type.
3. Deleted: this overload is only available if `T` is an integral type and is declared as deleted, so that a call with
an integer `key` (for example, `#!cpp j.find(0)`) fails to compile. Otherwise, the integer literal `0` would convert to
a null `#!cpp const char*` and, from there, to the key type, causing undefined behavior at runtime.
## Template parameters ## Template parameters
@@ -84,6 +93,7 @@ Logarithmic in the size of the JSON object.
- [count](count.md) returns the number of occurrences of a key - [count](count.md) returns the number of occurrences of a key
- [contains](contains.md) checks whether a key exists - [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 ## Version history
@@ -124,7 +124,8 @@ Linear in the size of the input.
!!! warning "Deprecation" !!! warning "Deprecation"
- Overload (2) replaces calls to `from_bjdata` with a pointer and a length as first two parameters, which has been - 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 deprecated in version 3.13.0. In version 4.0.0, this overload
will be deleted (`= delete`) rather than removed. Please replace all calls like
`#!cpp from_bjdata(ptr, len, ...);` with `#!cpp from_bjdata(ptr, ptr+len, ...);`. `#!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 You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
+2 -1
View File
@@ -110,7 +110,8 @@ Linear in the size of the input.
!!! warning "Deprecation" !!! warning "Deprecation"
- Overload (2) replaces calls to `from_bon8` with a pointer and a length as first two parameters, which has been - 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 deprecated in version 3.13.0. In version 4.0.0, this overload
will be deleted (`= delete`) rather than removed. Please replace all calls like
`#!cpp from_bon8(ptr, len, ...);` with `#!cpp from_bon8(ptr, ptr+len, ...);`. `#!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 You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
+2 -1
View File
@@ -126,7 +126,8 @@ Linear in the size of the input.
!!! warning "Deprecation" !!! warning "Deprecation"
- Overload (2) replaces calls to `from_bson` with a pointer and a length as first two parameters, which has been - Overload (2) replaces calls to `from_bson` with a pointer and a length as first two parameters, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. In version 4.0.0, this overload
will be deleted (`= delete`) rather than removed. Please replace all calls like
`#!cpp from_bson(ptr, len, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`. `#!cpp from_bson(ptr, len, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`.
- Overload (2) replaces calls to `from_bson` with a pair of iterators as their first parameter, which has been - Overload (2) replaces calls to `from_bson` with a pair of iterators as their first parameter, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like
+2 -1
View File
@@ -135,7 +135,8 @@ Linear in the size of the input.
!!! warning "Deprecation" !!! warning "Deprecation"
- Overload (2) replaces calls to `from_cbor` with a pointer and a length as first two parameters, which has been - Overload (2) replaces calls to `from_cbor` with a pointer and a length as first two parameters, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. In version 4.0.0, this overload
will be deleted (`= delete`) rather than removed. Please replace all calls like
`#!cpp from_cbor(ptr, len, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`. `#!cpp from_cbor(ptr, len, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`.
- Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been - Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like
@@ -127,7 +127,8 @@ Linear in the size of the input.
!!! warning "Deprecation" !!! warning "Deprecation"
- Overload (2) replaces calls to `from_msgpack` with a pointer and a length as first two parameters, which has been - Overload (2) replaces calls to `from_msgpack` with a pointer and a length as first two parameters, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. In version 4.0.0, this overload
will be deleted (`= delete`) rather than removed. Please replace all calls like
`#!cpp from_msgpack(ptr, len, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`. `#!cpp from_msgpack(ptr, len, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`.
- Overload (2) replaces calls to `from_msgpack` with a pair of iterators as their first parameter, which has been - Overload (2) replaces calls to `from_msgpack` with a pair of iterators as their first parameter, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like
@@ -125,7 +125,8 @@ Linear in the size of the input.
!!! warning "Deprecation" !!! warning "Deprecation"
- Overload (2) replaces calls to `from_ubjson` with a pointer and a length as first two parameters, which has been - Overload (2) replaces calls to `from_ubjson` with a pointer and a length as first two parameters, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. In version 4.0.0, this overload
will be deleted (`= delete`) rather than removed. Please replace all calls like
`#!cpp from_ubjson(ptr, len, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`. `#!cpp from_ubjson(ptr, len, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`.
- Overload (2) replaces calls to `from_ubjson` with a pair of iterators as their first parameter, which has been - Overload (2) replaces calls to `from_ubjson` with a pair of iterators as their first parameter, which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like
+1
View File
@@ -51,6 +51,7 @@ Constant.
## See also ## See also
- [back](back.md) to access the last element - [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 ## Version history
+2
View File
@@ -183,6 +183,8 @@ overload (3).
- [get_ref](get_ref.md) get a reference to the stored value - [get_ref](get_ref.md) get a reference to the stored value
- [operator ValueType](operator_ValueType.md) get a value via implicit conversion - [operator ValueType](operator_ValueType.md) get a value via implicit conversion
- [Converting values](../../features/conversions.md) - the type conversions article - [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 ## Version history
@@ -61,6 +61,8 @@ Constant.
## See also ## See also
- [get_ptr()](get_ptr.md) get a pointer value - [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 ## 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_ref](get_ref.md) get a reference to the stored value
- [get_ptr](get_ptr.md) get a pointer 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 - [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 ## Version history
@@ -40,6 +40,7 @@ Constant.
- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object) - [is_structured](is_structured.md) checks whether the JSON value is structured (array or object)
- [type](type.md) returns the type of the JSON value - [type](type.md) returns the type of the JSON value
- [array_t](array_t.md) the type used to store JSON arrays - [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 ## Version history
@@ -39,6 +39,7 @@ Constant.
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive - [is_primitive](is_primitive.md) checks whether the JSON value is primitive
- [binary_t](binary_t.md) the type used to store binary values - [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 - [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 ## Version history
@@ -38,6 +38,7 @@ Constant.
- [boolean_t](boolean_t.md) the type used to store JSON booleans - [boolean_t](boolean_t.md) the type used to store JSON booleans
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive - [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 ## 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" --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 ## Version history
- Added in version 1.0.0. - Added in version 1.0.0.
@@ -40,6 +40,7 @@ Constant.
- [is_object](is_object.md) checks whether the JSON value is an object - [is_object](is_object.md) checks whether the JSON value is an object
- [type](type.md) returns the type of the JSON value - [type](type.md) returns the type of the JSON value
- [value_t](value_t.md) the enumeration of JSON types - [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 ## 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_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_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 - [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 ## Version history
@@ -40,6 +40,7 @@ Constant.
- [is_number()](is_number.md) check if the value is a number - [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_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_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 ## Version history
@@ -40,6 +40,7 @@ Constant.
- [is_number()](is_number.md) check if the value is a number - [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_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 - [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 ## Version history
@@ -40,6 +40,7 @@ Constant.
- [is_number()](is_number.md) check if the value is a number - [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_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 - [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 ## Version history
@@ -40,6 +40,7 @@ Constant.
- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object) - [is_structured](is_structured.md) checks whether the JSON value is structured (array or object)
- [type](type.md) returns the type of the JSON value - [type](type.md) returns the type of the JSON value
- [object_t](object_t.md) the type used to store JSON objects - [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 ## 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_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_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 - [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 ## Version history
@@ -39,6 +39,7 @@ Constant.
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive - [is_primitive](is_primitive.md) checks whether the JSON value is primitive
- [type](type.md) returns the type of the JSON value - [type](type.md) returns the type of the JSON value
- [string_t](string_t.md) the type used to store JSON strings - [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 ## 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_primitive()](is_primitive.md) returns whether JSON value is primitive
- [is_array()](is_array.md) returns whether the value is an array - [is_array()](is_array.md) returns whether the value is an array
- [is_object()](is_object.md) returns whether the value is an object - [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 ## 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 - [begin](begin.md) returns an iterator to the first element
- [end](end.md) returns an iterator to one past the last 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 ## Version history
@@ -62,5 +62,5 @@ same name. Hidden members remain accessible via [`as_base_class`](as_base_class.
## Version history ## Version history
- Added in version 3.12.0. - Added in version 3.11.3.
- Made a public member type in version 3.13.0; it was private before, so it could not be named outside the class. - Made a public member type in version 3.13.0; it was private before, so it could not be named outside the class.
@@ -23,9 +23,10 @@ type to use.
## Template parameters ## Template parameters
`NumberFloatType` `NumberFloatType`
: the type to store floating-point numbers. Parsing and serialization are implemented in terms of : the type to store floating-point numbers. The type must be `#!cpp float`, `#!cpp double`, or
`#!cpp std::strtof`/`#!cpp std::strtod`/`#!cpp std::strtold` and `#!cpp std::snprintf`, so the type must be `#!cpp long double`. The parser converts `#!cpp float`, `#!cpp double`, and a `#!cpp long double` that is IEEE 754
`#!cpp float`, `#!cpp double`, or `#!cpp long double`. The binary64 itself. It converts other `#!cpp long double` formats with `#!cpp std::from_chars` where available, or
with `#!cpp std::strtold` otherwise. Serialization falls back to `#!cpp std::snprintf`. The
[binary formats](../../features/binary_formats/index.md) additionally require `#!cpp float` or `#!cpp double`, [binary formats](../../features/binary_formats/index.md) additionally require `#!cpp float` or `#!cpp double`,
because they have no encoding for `#!cpp long double`. See because they have no encoding for `#!cpp long double`. See
[Template Parameter Requirements](../../features/types/template_parameters.md#numberfloattype). [Template Parameter Requirements](../../features/types/template_parameters.md#numberfloattype).
+1 -2
View File
@@ -26,8 +26,7 @@ To store objects in C++, a type is defined by the template parameters described
`StringType` `StringType`
: the type of the keys or names (e.g., `std::string`). The comparison function `std::less<StringType>` is used to : the type of the keys or names (e.g., `std::string`). The comparison function `std::less<StringType>` is used to
order elements inside the container. `object_t::key_type` must be implicitly convertible to `string_t` (required by the order elements inside the container.
binary formats).
`AllocatorType` `AllocatorType`
: the allocator to use for objects (e.g., `std::allocator`) : the allocator to use for objects (e.g., `std::allocator`)
@@ -275,6 +275,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
- documentation on [runtime assertions](../../features/assertions.md) - documentation on [runtime assertions](../../features/assertions.md)
- see [`at`](at.md) for access by reference with range checking - see [`at`](at.md) for access by reference with range checking
- see [`value`](value.md) for access with default value - 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 ## Version history
@@ -286,4 +288,6 @@ Strong exception safety: if an exception occurs, the original value stays intact
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as 3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
already supported by [`at`](at.md), [`value`](value.md), [`find`](find.md), and other lookup functions. already supported by [`at`](at.md), [`value`](value.md), [`find`](find.md), and other lookup functions.
4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since 4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since
version 3.13.0. version 3.13.0. Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not
a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones.
@@ -171,6 +171,8 @@ Linear.
- [operator!=](operator_ne.md) compare for inequality - [operator!=](operator_ne.md) compare for inequality
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20) - [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 ## Version history
@@ -95,6 +95,8 @@ Linear.
- [operator==](operator_eq.md) comparison: equal - [operator==](operator_eq.md) comparison: equal
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20) - [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 ## Version history
+3
View File
@@ -112,3 +112,6 @@ is thrown. In any case, the original value is not changed: the patch is applied
location has a non-object/non-array parent in version 3.13.0. location has a non-object/non-array parent in version 3.13.0.
- Added [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper - Added [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper
prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0. prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0.
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is
not a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones.
@@ -110,3 +110,6 @@ function throws an exception.
location has a non-object/non-array parent in version 3.13.0. location has a non-object/non-array parent in version 3.13.0.
- Added [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper - Added [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper
prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0. prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0.
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is
not a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones.
+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 - [empty](empty.md) checks whether the JSON value has no elements
- [max_size](max_size.md) returns the maximum possible number of 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 ## Version history
@@ -41,6 +41,8 @@ With (2), the bytes written before the exception remain in the output adapter.
above 9223372036854775807, which BON8 cannot represent above 9223372036854775807, which BON8 cannot represent
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if `j` contains a string that is not - Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if `j` contains a string that is not
valid UTF-8 valid UTF-8
- 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 BON8"`
## Complexity ## Complexity
+1
View File
@@ -52,6 +52,7 @@ Constant.
- [operator value_t](operator_value_t.md) implicit conversion operator equivalent to this named member function - [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 - [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 - [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 ## Version history
@@ -56,6 +56,7 @@ Constant.
- [type](type.md) returns the type of the JSON value - [type](type.md) returns the type of the JSON value
- [value_t](value_t.md) the enumeration of JSON types - [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 ## Version history
+6 -2
View File
@@ -36,8 +36,9 @@ The function can throw the following exceptions:
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a key is not a - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a key is not a
number; example: `"array index 'one' is not a number"` number; example: `"array index 'one' is not a number"`
- Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a level becomes an array - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a level becomes an array
(because one of its keys is `0`) and another key at that level cannot be an array index; example: (because one of its keys is `0`) and another key at that level begins with a digit but is not a valid array index
`"unresolved reference token 'x'"` (such as `1a`), or is `-`; example:
`"unresolved reference token '-'"`
## Complexity ## Complexity
@@ -80,3 +81,6 @@ Apart from these two cases, for a JSON value `j`, the following is always true:
- Added in version 2.0.0. - Added in version 2.0.0.
- Made the array/object decision independent of the object's iteration order in version 3.13.0. - Made the array/object decision independent of the object's iteration order in version 3.13.0.
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is
not a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones.
+12 -1
View File
@@ -119,6 +119,14 @@ changes to any JSON value.
## Notes ## Notes
!!! warning "`null` members are not missing"
The default value is used only if the key (or JSON Pointer) does not exist. A member that exists but is
`#!json null` is converted like any other value, so `#!cpp j.value("k", 0)` throws a
[`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `"k"` is `#!json null`. See
[Access with default value](../../features/element_access/default_value.md)
for alternatives.
!!! warning "Return type" !!! warning "Return type"
The value function is a template, and the return type of the function is determined by the type of the provided The value function is a template, and the return type of the function is determined by the type of the provided
@@ -216,6 +224,7 @@ changes to any JSON value.
- see [`at`](at.md) for access by reference with range checking - see [`at`](at.md) for access by reference with range checking
- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference - 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 ## Version history
@@ -227,4 +236,6 @@ changes to any JSON value.
[`operator[]`](operator[].md), [`at`](at.md), [`find`](find.md), and other lookup functions. [`operator[]`](operator[].md), [`at`](at.md), [`find`](find.md), and other lookup functions.
3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0, including fixing an issue where resolving 3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0, including fixing an issue where resolving
`ptr` through an array unexpectedly threw `out_of_range` instead of returning the resolved element (or `ptr` through an array unexpectedly threw `out_of_range` instead of returning the resolved element (or
`default_value`, as documented). `default_value`, as documented). Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109)
instead of returning `default_value` for a one-character array index that is not a digit (e.g., `/x`) in version
3.13.0, as it already did for longer ones.
@@ -0,0 +1,72 @@
# <small>nlohmann::basic_json_document::</small>accept
```cpp
template<typename InputType>
static bool accept(InputType&& input,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
```
Checks whether the input is valid JSON, accepting and rejecting exactly what
[`BasicJsonType::accept()`](../basic_json/accept.md) does, with the same options. Unlike [`parse()`](parse.md), this
function never throws an exception for invalid input, and the returned `#!cpp bool` is the only result -- no document
is returned.
## Template parameters
`InputType`
: A compatible input; see [`parse`](parse.md#template-parameters).
## Parameters
`input` (in)
: Input to check.
`ignore_comments` (in)
: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
(`#!cpp false`); (optional, `#!cpp false` by default)
`ignore_trailing_commas` (in)
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or
yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default)
## Return value
Whether the input is valid JSON.
## Exception safety
Strong guarantee: this function itself never throws for an invalid input; it can only throw what allocating the
input's own copy (for inputs that are always read into a buffer) throws.
## Complexity
Linear in the length of the input.
## Notes
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp accept(ptr, len)`, does not
compile; see [`parse`](parse.md#notes).
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__accept.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__accept.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
- [`BasicJsonType::accept`](../basic_json/accept.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -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,154 @@
# <small>nlohmann::basic_json_document::</small>parse
```cpp
// (1)
template<typename InputType>
static basic_json_document parse(InputType&& input,
const bool allow_exceptions = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
// (2)
template<typename IteratorType>
static basic_json_document parse(IteratorType first, IteratorType last,
const bool allow_exceptions = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
```
1. Deserialize from a compatible input, borrowing or owning it depending on its value category and type (see Notes).
2. Deserialize from a pair of input iterators.
Both overloads accept the same JSON text as [`BasicJsonType::parse()`](../basic_json/parse.md), with the same
`ignore_comments`/`ignore_trailing_commas` options, but build a [`basic_json_document`](index.md) (a flat index into
the input) instead of a tree of `BasicJsonType` values. The input must be byte-oriented (see the template parameters
below): not every input type of `BasicJsonType::parse()` is supported.
## Template parameters
`InputType`
: A byte-oriented input, one of:
- a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of single-byte characters
- a pointer to a null-terminated string of single-byte characters (`#!cpp char`, `#!cpp signed char`,
`#!cpp unsigned char`, `#!cpp std::uint8_t`)
- a container for which `#!cpp obj.data()` and `#!cpp obj.size()` give contiguous single-byte access, e.g.
`#!cpp std::vector<char>` or `#!cpp std::vector<std::uint8_t>`
- an `#!cpp std::istream` object
- a wide string object (`#!cpp std::wstring`, `#!cpp std::u16string`, `#!cpp std::u32string`), which is converted
to UTF-8
Other inputs are not supported: a `#!cpp FILE*`, and pointers to or arrays of wide characters (`#!cpp wchar_t`,
`#!cpp char16_t`, `#!cpp char32_t`) are rejected at compile time by a `#!cpp static_assert`. (Use
[`BasicJsonType::parse()`](../basic_json/parse.md) for these.)
`IteratorType`
: an input iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of
`#!cpp std::string::iterator`; the iterators of single-byte characters are borrowed or read like the byte inputs
above, those of wide characters are converted to UTF-8
## Parameters
`input` (in)
: Input to parse from.
`allow_exceptions` (in)
: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)
`ignore_comments` (in)
: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
(`#!cpp false`); (optional, `#!cpp false` by default)
`ignore_trailing_commas` (in)
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or
yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default)
`first` (in)
: iterator to the start of a character range
`last` (in)
: iterator to the end of a character range
## Return value
The parsed document. If `allow_exceptions` is `#!cpp false` and the input is not valid JSON, the returned document is
discarded; see [`is_discarded`](is_discarded.md).
## Exceptions
Throws the same exception [`BasicJsonType::parse()`](../basic_json/parse.md) throws for the same input and options --
the same exception id, message, and position -- because on a failing input the library's own parser is run on the
same bytes to produce the diagnostic. Additionally throws
[`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the input is 4294967280 bytes (4 GiB
minus 16 bytes) or larger, a size [`BasicJsonType::parse()`](../basic_json/parse.md) does not reject.
## Complexity
Linear in the length of the input.
## Notes
**Ownership.** Whether the document borrows `input` or owns a copy of it depends on its value category and type:
| `input` | ownership |
|--------------------------------------------------------------------------------------|--------------------------------------------------------------|
| lvalue byte container (`std::string`, `std::vector<char>`, ...), `std::string_view`, C string, character array | **borrowed** -- `input` must outlive the document |
| non-const rvalue `#!cpp std::string` | **owned**, moved in without a copy |
| other rvalue byte container (including a `#!cpp const` rvalue `#!cpp std::string`) | **owned**, copied |
| stream, wide string, or anything else read through the general input adapter | **owned**, read into a buffer (a stream is read to its end) |
For overload (2), a pair of pointers to single-byte integers (e.g. `#!cpp const char*`, `#!cpp std::uint8_t*`) is
borrowed. From C++20 on, so is any other contiguous iterator over single bytes, such as
`#!cpp std::vector<char>::iterator` or `#!cpp std::string::const_iterator`. Before C++20 these iterators cannot be
told apart from other class-type iterators, so their range is read into an owned buffer, as is any non-contiguous
range (e.g. of a `#!cpp std::list<char>`).
See [`owns_source`](owns_source.md) to check which happened after a call, and the
[feature page](../../features/json_view.md) for the reasoning.
**Numbers.** As for [`BasicJsonType::parse()`](../basic_json/parse.md), an integer literal too large for the 64-bit
integer type becomes a floating-point value.
**No lengths.** An integer argument that is not a `#!cpp bool` where the flags are expected -- for example
`#!cpp parse(ptr, len)` -- does not compile (the overload is deleted). Such a call would convert `len` to
`allow_exceptions` and read `ptr` as a null-terminated string, past the end of a buffer that has none. To parse a
buffer of a given length, pass a pair of pointers: `#!cpp parse(ptr, ptr + len)`. The same holds for
[`parse_copy`](parse_copy.md), [`accept`](accept.md), and [`read`](read.md).
## Examples
??? example "Example: (1) borrowed vs. owned input, and errors identical to `BasicJsonType::parse()`"
```cpp
--8<-- "examples/basic_json_document__parse.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__parse.output"
```
??? example "Example: (2) parse an iterator range (no NUL terminator required)"
```cpp
--8<-- "examples/basic_json_document__parse_iterator_pair.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__parse_iterator_pair.output"
```
## See also
- [parse_copy](parse_copy.md) - deserialize a copy of a compatible input
- [accept](accept.md) - check whether the input is valid JSON
- [read](read.md) - (re-)parse into this document, reusing its memory
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
- [`BasicJsonType::parse`](../basic_json/parse.md) - the corresponding function of `basic_json`
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,80 @@
# <small>nlohmann::basic_json_document::</small>parse_copy
```cpp
template<typename InputType>
static basic_json_document parse_copy(InputType&& input,
const bool allow_exceptions = true,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
```
Deserialize from a compatible input, always taking the document's own copy of it, regardless of the value category or
type of `input`. Unlike [`parse()`](parse.md), the returned document never depends on `input` staying alive.
## Template parameters
`InputType`
: A compatible input; see [`parse`](parse.md#template-parameters).
## Parameters
`input` (in)
: Input to parse from.
`allow_exceptions` (in)
: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default)
`ignore_comments` (in)
: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error
(`#!cpp false`); (optional, `#!cpp false` by default)
`ignore_trailing_commas` (in)
: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or
yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default)
## Return value
The parsed document, with [`owns_source()`](owns_source.md) `#!cpp true`. If `allow_exceptions` is `#!cpp false` and
the input is not valid JSON, the returned document is discarded; see [`is_discarded`](is_discarded.md).
## Exceptions
Same as [`parse`](parse.md#exceptions).
## Complexity
Linear in the length of the input.
## Notes
`parse_copy()` accepts and rejects exactly what [`parse()`](parse.md) does, and classifies numbers the same way; it
only differs in that the input is always copied rather than sometimes borrowed. Prefer [`parse()`](parse.md) when the
input's lifetime already covers the document's, since it avoids the copy for borrowed inputs.
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp parse_copy(ptr, len)`, does not
compile; see [`parse`](parse.md#notes).
## Examples
??? example
The example below returns a document from a function whose local buffer would otherwise not outlive it.
```cpp
--8<-- "examples/basic_json_document__parse_copy.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__parse_copy.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input, borrowing it where possible
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
## Version history
- Added in version 3.13.0.
@@ -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,84 @@
# <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()`.
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp read(ptr, len)`, does not
compile; see [`parse`](parse.md#notes).
## Examples
??? example
The example below parses a sequence of messages into the same document, reusing its memory instead of allocating
a new document for each one.
```cpp
--8<-- "examples/basic_json_document__read.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__read.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
- [root](root.md) - the view of the root value
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,65 @@
# <small>nlohmann::basic_json_document::</small>root
```cpp
// (1)
view_type root() const& noexcept;
// (2)
view_type root() const&& = delete;
```
1. Returns a view of the root value of the document.
2. Deleted: the view of a temporary document would dangle.
## Return value
A [`view_type`](index.md#member-types) (i.e. `#!cpp basic_json_view<BasicJsonType>`) for the root value, or a
discarded view if the document is [discarded](is_discarded.md).
## Exception safety
No-throw guarantee: this function never throws exceptions.
## Complexity
Constant.
## Notes
**Lifetime.** A view refers into the document, so the document must outlive it. `root()` can therefore only be called
on a document that has a name (an lvalue); calling it on a temporary does not compile:
```cpp
auto v = json_document::parse(text).root(); // error: the document is destroyed at the end of the statement
auto doc = json_document::parse(text); // OK: keep the document alive
auto v = doc.root();
```
`root()` is a cheap handle into the document's index, not a copy of anything; call it as often as needed. The
returned view is valid under the same conditions as any other view of the document -- see
[Object inspection](../basic_json_view/index.md) -- in particular, it is invalidated by the next
[`read()`](read.md) or [`shrink_to_fit()`](shrink_to_fit.md) on this document.
## Examples
??? example
```cpp
--8<-- "examples/basic_json_document__root.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__root.output"
```
## See also
- [is_discarded](is_discarded.md) - return whether the last parse failed
- [materialize](../basic_json_view/materialize.md) - build the `BasicJsonType` value of a subtree
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,203 @@
# <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. A [null](../basic_json_view/is_null.md) parent becomes what
[`basic_json::operator[]`](../basic_json/operator%5B%5D.md) with a JSON pointer makes of it: an array if the last
reference token is `#!cpp "-"` or consists of digits only (for an index beyond 0, the array is first filled with
null values up to that index), an object otherwise. 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. Likewise, a failure of `value` in 4. leaves a null parent that is set with an
index beyond 0 already filled with the null values before the index.
## 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); the same errors are
thrown for a null parent and a token of digits (the parent is not changed then), and
[`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if the index is 4294967295 or more.
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 size of the document, the *first* time (the parent of `target` is looked up from
[`root()`](root.md), and then switches to links) -- see [Notes](#notes). Once the parent has links, `target` is
replaced in constant time: setting every element of a large array one after the other is linear overall. To avoid
the lookup altogether, use 3. (or 2. for an object), which know the parent.
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; for a null parent and an index, linear in the index.
## 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.
+144
View File
@@ -0,0 +1,144 @@
# <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;
template<typename IntegerType>
basic_json_view at(IntegerType 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`. The template accepts every integer type except `#!cpp bool` and
`#!cpp std::size_t` and forwards to the `size_type` overload, as for [`operator[]`](operator[].md); a negative
`idx` is out of range.
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
!!! warning "Duplicate keys: the first member wins"
If the source text repeats a key, this resolves to the *first* member with it, not to the last one that
[`materialize()`](materialize.md) and `parse()` keep. See the [Notes on duplicate keys](operator[].md#notes) of
`operator[]` and [Duplicate keys](../../features/json_view.md#duplicate-keys) for the reasons and for how to get
the last value.
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,51 @@
# <small>nlohmann::basic_json_view::</small>basic_json_view
```cpp
basic_json_view() noexcept = default;
```
Creates an invalid (discarded) view: [`type()`](type.md) is `#!cpp value_t::discarded` and
[`is_discarded()`](is_discarded.md) is `#!cpp true`.
This is the only constructor a caller can use directly. Every other view is obtained from a
[`basic_json_document`](../basic_json_document/index.md), via [`root()`](../basic_json_document/root.md) or 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
- [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.
Loaded 100 of 429 files, more files were not shown because too many files have changed in this diff. Show more