Compare commits

...
Author SHA1 Message Date
Niels Lohmann 289d61ef4f Merge branch 'develop' into docs/review-fixes
Conflicts:
- include/nlohmann/json.hpp: took develop's removal of the UDLs (moved to json_literals.hpp, which already has the corrected @sa links)
- single_include/nlohmann/json.hpp: regenerated with make amalgamate
- docs/mkdocs/docs/api/operator_literal_json.md, operator_literal_json_pointer.md: kept the PR's migration guide link and develop's json_literals.hpp/JSON_NO_AUTOMATIC_UDLS note
- docs/mkdocs/docs/api/basic_json/to_bson.md: both sides added out_of_range.415; kept develop's example message and both version history lines
- docs/docset/docSet.sql: added JSON_NO_AUTOMATIC_UDLS (new on develop), which the PR's check_structure.py requires

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:39:42 +02:00
Niels Lohmann 6a073dbae4 Give operator>> a strong exception-safety guarantee (#5695)
operator>> parsed directly into its basic_json& target, so a parse
error left the target holding whatever was parsed before the error
instead of its previous value. With JSON_DIAGNOSTICS=1, that partial
value also violated the class invariant, because the parent pointers
of an array or object's elements are only set when the container is
closed, which a failed parse never reaches; copying such a value then
aborted in assert_invariant().

Fix it the way basic_json::parse() already handles this: parse into a
temporary and move it into the target only once parsing succeeds, so
the target is left unchanged if an exception is thrown.

Fixes #5652.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:13:34 +02:00
Niels Lohmann fdcc569eee Use only documented StringType members in json_pointer (#5692)
contains(const json_pointer&) and operator/=(std::size_t) (and hence
operator/(std::size_t)) used string_t operations that the StringType
template parameter documentation explicitly does not require:
comparing string_t with a const char* literal, c_str(), and
constructibility from std::string. This made both functions fail to
compile for a conforming custom StringType, even though the
documentation's own reference StringType satisfies the requirements.

Fix contains() to compare individual chars ('0'..'9') instead of
comparing string_t with const char* literals, and to call data()
(documented to be null-terminated) instead of c_str(). Fix
operator/=(std::size_t) to build the array-index token via the
existing detail::to_string<StringType> helper (ADL int_to_string() or
assignment from std::to_string()) instead of via std::to_string()
directly, matching how diff(), items(), and std::hash already convert
a std::size_t to a StringType.

Add regression tests to tests/src/unit-alt-string.cpp: contains() for
present/missing keys and indices, "-", a leading zero, and a
non-numeric token on an array, plus json_pointer::operator/(std::size_t).

Fixes #5666.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:13:31 +02:00
Niels Lohmann 6fc0d501f3 Move the user-defined string literals to <nlohmann/json_literals.hpp> and add JSON_NO_AUTOMATIC_UDLS (#5610)
* Add JSON_NO_UDLS to leave out the user-defined string literals

The bodies of operator""_json and operator""_json_pointer call the
parser, so every translation unit including the library instantiates it,
even if it never parses anything. Defining JSON_NO_UDLS leaves the
literals out entirely, which saves 15-35% compile time for such
translation units (#5294). Nothing changes if the macro is not defined.

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

* Mention JSON_NO_UDLS in the list of exported module symbols

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

* Move the user-defined string literals to <nlohmann/json_literals.hpp>

Following the review in #5294, the literals now live in their own header
instead of being removed entirely: <nlohmann/json.hpp> includes it at the
end unless JSON_NO_AUTOMATIC_UDLS (renamed from JSON_NO_UDLS) is defined,
so a project can opt out globally and include the header only where the
literals are used.

The header only uses public and standard macros, because the library's
internal macros are undefined at the end of json.hpp and the amalgamation
inlines macro_scope.hpp only once. For the same reason, the library no
longer defines and undefines JSON_USE_GLOBAL_UDLS, so a user's definition
is still visible to the header. The single-header copy is identical to
the multi-header one, as it only includes <nlohmann/json.hpp>. The module
always exports the literals.

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

* Fix CI: include cycle, GCC 4.8 literal operator spacing, and global UDLs off in the JSON_NO_AUTOMATIC_UDLS test

- Suppress clang-tidy misc-header-include-cycle on the intentional mutual
  include of json.hpp and json_literals.hpp.
- Use operator"" _json with a space for GCC 4.8 in the test's detection
  aliases, as the header does.
- Only test the global literal operators when JSON_USE_GLOBAL_UDLS is on.

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

* Declare the literal operators through a local macro

The GCC 4.8 spacing condition was repeated for both operator definitions
and the global using-declarations. NLOHMANN_JSON_LITERAL_OPERATOR(suffix)
now selects operator""##suffix or operator"" suffix in one place and is
undefined at the end of json_literals.hpp.

Suggested by gregmarr in review.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:08:17 +02:00
Niels Lohmann 67435c9c7e Give a deep copy its type only after its container exists (#5721)
When copying a value nested deeper than 128 levels, and an allocation
fails while an inner array or object is being copied, the partially
built copy ended up with an element typed array/object but holding a
null pointer. That element was already a fully constructed member of
its parent's container, so destroying the parent during stack
unwinding dereferenced the null pointer (release builds) or failed
assert_invariant() (debug builds), instead of letting std::bad_alloc
reach the caller.

copy_iteratively() set a pending worklist element's type right after
popping it, before the next loop iteration created its container in
copy_array_level()/copy_object_level(). Move that type assignment into
those two functions, right after the container is successfully
created, and drop the premature one in copy_iteratively(), so a
half-built element stays a null value - as copy_shallow()'s comment
already promised - until it can safely hold one.

Add a regression test to tests/src/unit-allocator.cpp that copies a
value nested 130 levels deep (both arrays and objects, with a
std::map- and an ordered_map-backed object_t) and fails every
allocation of the copy in turn: each attempt must throw std::bad_alloc
without crashing, and the source must stay unchanged.

Fixes #5640.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:08:00 +02:00
Niels Lohmann 2ea6d8c127 Require the found key to equal the looked-up key when comparing objects (#5720)
For an object type whose comparator treats unequal keys as equivalent
(for example a std::map with a case-insensitive comparator),
compare_iteratively() looked up a mismatched left key in the right
object with find(), which uses the object's own comparator, and
accepted whatever entry it found without checking that the keys are
actually equal. A case-insensitive comparator then found "KEY" for
"key", so two objects nested past the recursion bound (or at every
depth with JSON_NO_THREAD_LOCAL) could compare equal even though the
object type's own operator== - and basic_json itself, below the bound
- consider them different.

Accept the found entry only if its key equals (not just compares
equivalent to) the looked-up key.

Fixes #5655.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:56 +02:00
Niels Lohmann 66877675b1 Check the iterator range for binary values in basic_json(first, last) (#5719)
basic_json(first, last) treated value_t::binary like the structured
types (array, object) in the range check, so it always copied the
whole binary value regardless of the iterators, even for an empty
range such as (b.end(), b.end()). The other primitive types (number,
boolean, string) already reject such a range with
invalid_iterator.204, and erase(first, last) already does the same
for binary values, so this made the constructor inconsistent with
both. Move case value_t::binary into the group of checked primitive
types.

Also update the two matching passages in basic_json.md that describe
overload 7, and add a version-history note.

Fixes #5670.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:52 +02:00
Niels Lohmann 7fd6895788 Hide a discarded container's content from the parser callback (#5706)
When a parser callback rejects an object's or array's start event,
json_sax_dom_callback_parser kept calling it for everything inside
that container anyway: nested keys, values, and the start/end events
of containers below it. This contradicts parser_callback_t's own
documentation, which promises that discarding a container at its
start event also hides its content from the callback.

The same code path also kept a full copy of every key inside such a
discarded container in key_stack until the whole parse finished,
because the early return for values that are not stored skipped the
matching pop. Filtering out a large subtree is the main reason to use
a callback, so this made peak memory during the parse scale with the
size of the very subtree the callback was trying to skip.

Fix start_object(), start_array(), and key() so that a container
whose own start event was discarded, or that is nested inside one, is
never handed to the callback, and no longer pushes onto the key
stacks. A container whose start event was accepted but whose key was
rejected still gets its content reported, as documented ("the
callback is still called for the associated value, but its return
value has no further effect"); only its own bookkeeping is skipped
since it will not be stored.

Fixes #5643.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:48 +02:00
Niels Lohmann 6ae17630a4 Reject integral keys for contains(), find(), and count() at compile time (#5705)
j.contains(0), j.find(0), and j.count(0) used to compile: the literal 0 is
a null pointer constant, so it converts to a null const char*, and the
overloads taking const typename object_t::key_type& accepted it by
constructing a std::string from that null pointer, which is undefined
behavior (a crash with both libc++ and libstdc++). value(0, default_value)
had the same problem in C++11, where the object comparator is not
transparent.

Add deleted overloads for integral arguments to contains(), find()
(const and non-const), count(), and value() so that these calls are
compile errors in every supported language mode instead of crashing.
Calls with string, string_view, json_pointer, and size-typed element
access (at(), operator[](), erase()) are unaffected.

Fixes #5657.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:45 +02:00
Niels Lohmann 5bd766aa50 Move to_bson's binary subtype check into calc_bson_sizes (#5703)
to_bson() rejected a binary value's subtype above 255 (out_of_range.415)
in write_bson_binary(), which only has the binary_t, not the basic_json
value that holds it, so the exception was created with no JSON_DIAGNOSTICS
context even though the equivalent to_msgpack() check names the value's
path. The check also ran after the document size, all preceding elements,
and this element's header and length had already reached the output
adapter, so a caller-provided std::vector or std::string ended up holding
a truncated document.

calc_bson_sizes() already walks every value before anything is written,
to size embedded documents and arrays and to reject invalid keys
(out_of_range.409) up front. The subtype check now runs there instead,
in calc_bson_binary_size(), which is given the basic_json value so the
exception can use it as context. The now-redundant check in
write_bson_binary() is removed, since calc_bson_sizes() always throws
first if any binary value in the document has an oversized subtype.

Fixes #5675.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:41 +02:00
Niels Lohmann 4bb1b14b06 Trim the compiler-appended NUL from wide/UTF string literals too (#5702)
With JSON_STRICT_NUL_HANDLING defined to 1, parsing a wide, UTF-16,
UTF-32, or (C++20) UTF-8 string literal (e.g. json::parse(L"[1]"))
failed with parse_error.101 at the terminating NUL of the literal,
and accept() returned false. The array overload of input_adapter()
only dropped the compiler-added trailing '\0' for arrays of char,
so for wchar_t, char16_t, char32_t, and char8_t arrays that
terminator was passed to the parser as data, which the macro then
rejected.

Broaden the trimming to every character type that a string literal
can use (char, wchar_t, char16_t, char32_t, and, since C++20,
char8_t). Arrays of any other element type (unsigned char,
std::uint8_t, ...), as used for CBOR/MessagePack, are unaffected: a
trailing zero byte there is still read as genuine data.

Fixes #5658.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:37 +02:00
Niels LohmannandClaude Sonnet 5 bfe0f32d71 Fix std::terminate and null pointer access in input_stream_adapter (#5699)
Parsing from a std::istream crashed in two unusual but valid stream
states, both in input_stream_adapter:

- With eofbit in the stream's exceptions() mask, get_character() sets
  eofbit via is->clear(), which throws std::ios_base::failure. While
  that exception unwinds, ~input_stream_adapter() called clear() again
  to reset eofbit, which is still set and still in the exception mask,
  so it throws a second time out of the (implicitly noexcept)
  destructor and std::terminate() is called. The destructor now only
  calls clear() if a bit other than eofbit remains set, so the first
  exception can propagate normally.
- For an std::istream without a stream buffer (rdbuf() == nullptr,
  e.g. std::istream(nullptr)), the constructor stored the null
  pointer without checking it, and get_character() dereferenced it.
  input_adapter(std::istream&) now throws parse_error.101 for such a
  stream, the same as it already does for a null FILE* or char*.

Added regression tests to unit-deserialization.cpp and, for the
JSON_PRECISE_STREAM_POSITION variant of get_character(), to
unit-precise-stream-position.cpp; both crashed before this fix.
Documented the two exceptions in parse.md and operator_gtgt.md.

Fixes #5646.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 20:07:33 +02:00
Niels Lohmann 44a88d85be Fix NLOHMANN_JSON_SERIALIZE_ENUM_STRICT's from_json message (#5698)
from_json built its out_of_range.410 message with "..." + j.dump(). If the
unmatched value is (or contains) a string with invalid UTF-8, that dump()
itself throws type_error.316, so the caller got type_error.316 instead of
the documented out_of_range.410; such strings can reach get<Enum>()
unvalidated, e.g. from from_cbor()/from_msgpack(). With a custom string_t,
j.dump() returns that type, and "const char*" + string_t does not compile
unless the type happens to provide operator+, so the macro failed to
compile for such types.

Build the message with detail::concat(), which appends any type exposing
data()/size() and always yields a std::string, and dump with
error_handler_t::replace so building the message itself cannot throw.

Added regression tests: an invalid-UTF-8 case in the existing strict-enum
test in unit-conversions.cpp, and a strict-enum use with alt_string (the
custom string_t from unit-alt-string.cpp) to cover the compile failure.

Fixes #5667.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:29 +02:00
Niels Lohmann 5b11a0282c Exchange the CustomBaseClass subobject in basic_json::swap() (#5697)
basic_json::swap() (and the friend swap() and the pre-C++20 std::swap
overload that forward to it) only exchanged m_data.m_type/m_data.m_value,
leaving each value's json_base_class_t subobject in place. This is
inconsistent with the copy and move constructors and copy assignment,
which all carry the base class along with the value, so after
a.swap(b) any metadata stored in a CustomBaseClass ended up attached to
the wrong value. Algorithms that mix swap() with moves, such as
std::sort, scrambled the metadata across the whole container.

Fix the member swap() to also exchange the json_base_class_t subobject
and extend the noexcept specifications of swap() and the friend swap()
accordingly.

Fixes #5653.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:24 +02:00
Niels Lohmann bfea6f36d3 Fix to_msgpack() reading the inactive number union member (#5694)
* Fix to_msgpack() reading the inactive number union member

basic_json stores number_integer and number_unsigned in a union, and
number_unsigned_t only has to be at least as wide as number_integer_t
(with the default types, both are 64-bit and have the same
representation). When number_integer_t is narrower, write_msgpack()
read the wrong union member in two places:

- The number_unsigned case wrote number_integer's bits instead of
  number_unsigned's, silently writing the wrong value whenever it
  did not fit in number_integer_t.
- The number_integer case (non-negative branch) picked the encoded
  width by comparing number_unsigned's bits, which is undefined
  behavior, though the value written was still number_integer's, so
  at worst a too-wide encoding was chosen.

Read the active member in both cases, like the other binary writers
(CBOR, UBJSON, BJData, BSON, BON8) already do.

Fixes #5644.

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

* Cast number_integer to number_unsigned_t only once in to_msgpack()

Addresses review comment by @gregmarr.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:19 +02:00
Niels Lohmann e444a66276 Copy values before inserting an initializer list into an array (#5693)
* Copy values before inserting an initializer list into an array

insert(pos, {...}) inserted wrong values when the initializer list
contained const references to elements of the array being inserted
into. json_ref stores only a pointer for a const lvalue, so the
initializer_list_t range passed straight to the array's range insert
aliased the array's own storage; std::vector::insert(pos, first, last)
may move or shift elements before copying from that range, so the
source elements were already stale by the time they were read
(different wrong results on libc++ and libstdc++).

Copy the referenced values into a temporary array_t first, then move
that temporary into place, so the source range never aliases the
array being modified.

Fixes #5656.

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

* Use the reserve_array helper in the initializer_list insert fix

The previous commit called array_t::reserve() directly on the
temporary buffer used to copy an ilist's values before inserting.
std::deque, a documented ArrayType (tests/src/unit-custom-array-type.cpp),
has no reserve(), so insert(pos, initializer_list) no longer compiled
for it. Use the existing detail::reserve_array() SFINAE helper (already
used by the SAX DOM parser) instead, which leaves array types without
reserve() untouched.

Added a regression check that deque_json::insert(pos, {...}) compiles
and handles the aliasing case from #5656.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:16 +02:00
Niels Lohmann 1151826508 Take diff()'s fast path unless the object type reorders members (#5691)
* Take diff()'s fast path unless the object type reorders members

For every object type except an insertion-ordered one like ordered_map,
diff() no longer produced a member-by-member patch when target had a key
that sorts before a key the two objects share: it fell through to the
slow path, which removes every member of source and re-adds every member
of target, instead of just adding the new key.

#5465 added an order check to require the fast path to also reproduce
target's member order, needed because ordered_map's patch()-driven "add"
appends a new member at the end. The check compared the common keys'
order between source and target and also required that every added key
come after every common key in target's order ("new_keys_form_suffix").
The comment above it argued this check is always true for std::map, and
that reasoning is correct for the order of the common keys themselves,
but not for new_keys_form_suffix: a std::map iterates in sorted key
order, so a new key that sorts before an existing common key is
enumerated between common keys, making new_keys_form_suffix false even
though std::map's own key order does not need reordering at all - it
places every member itself, regardless of insertion history, so a
member-by-member diff already reproduces target's iteration order.

Only require the order check for an object type that keeps insertion
order, using the same detail::is_ordered_map trait the library already
uses to recognize such an object type in set_parent(). Every other
object type - std::map in key order, a hash map in an order its
operator== ignores - always takes the fast path.

Added a regression test to unit-json_patch.cpp: the issue's example now
yields a single "add" op for json, while ordered_json still takes the
slow path to reproduce target's member order.

Fixes #5639.

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

* Only track the target key order in diff() for insertion-ordered objects

common_keys_target_order and new_keys_form_suffix are only read when object_t keeps its members in insertion order; skip building them otherwise. Addresses review comment by @gregmarr.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:10 +02:00
Niels Lohmann 6218aa212b Throw std::length_error for operator[](SIZE_MAX) instead of corrupting the array (#5687)
For idx == SIZE_MAX, the non-const array operator[] computed the new size as
idx + 1, which wraps to 0. resize(0) then emptied the array, and the
subsequent operator[](idx) on the now-empty vector wrote one element before
its buffer. Every other too-large index (e.g. SIZE_MAX - 1) already went
through resize(), which throws std::length_error and leaves the array
unchanged; SIZE_MAX was the one value for which the overflow bypassed that
safety net.

Add a guard that throws std::length_error before computing idx + 1 when idx
is the largest representable size_type value, so the array is left
unchanged, matching the exception vector::resize() already throws for
smaller (but still too large) indices.

Fixes #5647.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:06 +02:00
Niels Lohmann 42f89e3130 Let to_json(std::optional<T>) propagate exceptions from T's to_json (#5684)
* Let to_json(std::optional<T>) propagate exceptions from T's to_json

The overload was marked noexcept even though its body assigns *opt to
the JSON value, which calls T's to_json (or allocates for std::string,
std::vector, or json). Any exception from there -- a user-defined
to_json reporting an error, or std::bad_alloc -- called std::terminate()
instead of propagating. The noexcept also made basic_json's converting
constructor noexcept(true) for std::optional<T>, so json j = opt; could
not report the error either.

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

* Fix CI: make to_json(std::optional<T>) conditionally noexcept

GCC's -Wnoexcept (an error in ci_test_gcc) fired at to_json_fn's
noexcept(noexcept(to_json(j, val))): after dropping the unconditional
noexcept, to_json(std::optional<int>) had no exception specification
although GCC could prove its body cannot throw. It also made
json(std::optional<int>) lose its noexcept.

Declare the overload noexcept exactly when assigning the contained
value to the JSON value is (std::is_nothrow_assignable<BasicJsonType&,
const T&>), which is what the body does. std::optional<int> is noexcept
again; a T whose to_json may throw still propagates the exception.
Static assertions in the test check both cases.

The test's throwing to_json triggered -Wmissing-prototypes and
-Wmissing-noreturn (clang) and -Wmissing-declarations and
-Wsuggest-attribute=noreturn (GCC). Move the type and its to_json into
an anonymous namespace, mark the function [[noreturn]], and compile
them only without JSON_NOEXCEPTION, like the test that uses them.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:07:02 +02:00
Niels Lohmann 6d7845d207 Fix deprecated json_pointer/string operator== warning in value() (#5683)
value(KeyType&&, default) is constrained on is_comparable_with_object_key,
which passes KeyType as a reference. is_comparable's dispatch on
is_json_pointer_of<A, B> only matches a json_pointer as a plain type or a
plain reference, so a const-qualified reference (as produced when KeyType
is deduced from a json_pointer argument) fell through to
is_comparable_no_json_pointer, which instantiates the deprecated
json_pointer/string comparison operators. This made ordered_json's
transparent comparator (and any transparent comparator on a custom string
type) warn under -Wdeprecated-declarations when calling
value(json_pointer, default), even though no such comparison is ever
performed. at() was already fixed for this in #5289, which does not use
is_comparable_with_object_key.

Strip references and cv-qualifiers with uncvref_t before the
is_json_pointer_of dispatch, so any reference-to-json_pointer is
recognized regardless of qualifiers.

Fixes #5664.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:59 +02:00
Niels Lohmann 678fd3017b Fix element path for map/unordered_map JSON_DIAGNOSTICS errors (#5681)
When converting a JSON array to std::map or std::unordered_map with a
non-string key, each element must itself be a [key, value] array. If an
element is not an array, from_json() threw type_error 302 with the outer
array's value (&j) as the exception context, so with JSON_DIAGNOSTICS
enabled the message pointed at the whole array instead of the offending
element (e.g. "(/outer/m)" instead of "(/outer/m/2)"), even though the
message text already described the element's type.

Both from_json() overloads now pass the element (&p) as the context, so
the reported JSON Pointer matches the type named in the message, the
same way std::vector<std::vector<T>> and similar conversions already do.

Fixes #5668.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:55 +02:00
Niels Lohmann fc4c9c3446 Fix clear() to also reset the subtype of a binary value (#5680)
* Fix clear() to also reset the subtype of a binary value

clear() on a binary value cleared the bytes but left the subtype
untouched, so the result was not equal to a default-constructed
binary value even though the documentation says clear() has the same
effect as *this = basic_json(type()). The fix calls
byte_container_with_subtype::clear_subtype() alongside the existing
clear() call.

Extended the "filled binary" clear() test in unit-modifiers.cpp with
a case that uses a subtype, since the existing cases only covered
binary values without one.

Fixes #5669.

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

* Fix the table alignment in clear.md

Addresses review comment by @gregmarr.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:51 +02:00
Niels Lohmann 68beba727c Fix from_json() for enums with underlying type bool (#5679)
get_arithmetic_value() rejects boolean_t, so the default from_json()
for enums failed to compile for an enum whose underlying type is
bool (e.g. enum class Flag : bool { off, on }), even though the
matching to_json() serializes such enums as an unsigned number.

Read the underlying value through number_unsigned_t in that case,
matching what to_json() writes, then cast back to the underlying
type before constructing the enum.

Fixes #5671.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:46 +02:00
Niels Lohmann 0050d0f7a4 Share one nesting depth limit between all bounded descents (#5637)
Copying and comparing stopped their descent at
basic_json::nesting_depth_limit(), while serializing, hashing and
merging used detail::recursion_depth_limit(). Both were 128, but
nothing kept them equal. The thread-local count now tests against
detail::recursion_depth_limit() as well, and a static_assert keeps
the limit small enough for the byte that holds the count.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:43 +02:00
Niels Lohmann 6a8a7735ed Do not throw in contains() for an empty array reference token (#5614)
* Do not throw in contains() for an empty array reference token

json_pointer::contains() rejected malformed array indices, but an empty
reference token (e.g. "/a/" where "a" is an array, or "/" on an array)
passed every check and reached array_index(), which throws
out_of_range.404. contains() must not throw (cf. #5395), so it now
returns false for an empty token. at() still throws out_of_range.404.

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

* Fix CI: bind j_nested_const by reference in the json_pointer test

clang-tidy (ci_clang_tidy) flagged the new test with
performance-unnecessary-copy-initialization: the local copy
j_nested_const of j_nested is never modified. Bind it as a const
reference instead; it still exercises the const overloads of at() and
contains().

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:39 +02:00
Niels Lohmann 65af260117 Move instead of deep-copy ordered_json values when an object grows (#5609)
* Move instead of deep-copy ordered_json values when an object grows

ordered_map keeps its elements in a std::vector<std::pair<const Key, T>>.
With a std::string key, that pair is not nothrow move constructible (the
const key has to be copied), so std::vector copies every element when it
reallocates. For ordered_json, this deep-copies every member value an
object already holds, including whole nested subtrees, on each growth
step.

Grow the storage in ordered_map instead, copying the keys and moving the
values. This happens in two phases, so the strong exception guarantee is
kept without try/catch. The first phase may throw, but only touches a
temporary buffer: it copies the keys, value-initializes the values, and
constructs the new element. The second phase moves the values (noexcept)
and swaps the buffers. Because the new element is constructed before any
value is moved, arguments that refer to elements of the container stay
valid, as with std::vector. Types that cannot take this path keep the
std::vector behavior.

Parsing into ordered_json (ParseStringOrdered, Apple M1 Max, clang -O3):
twitter 3.20 -> 1.70 ms, citm_catalog 7.73 -> 3.67 ms, jeopardy 219 ->
177 ms, canada unchanged. The number of allocations for twitter and
citm_catalog drops by two thirds.

Also add ParseStringOrdered rows to the benchmarks, and document the
growth behavior and the exception safety of ordered_map.

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

* Fix CI: skip std::pair noexcept assumptions on EDG-based compilers

ci_icpc and ci_nvhpc failed to compile unit-ordered_map.cpp: the static
assertion that std::pair<const std::string, ordered_json> is not nothrow
move-constructible fails there. The EDG front end (Intel icpc 2021.10,
NVIDIA nvc++ 25.5) considers the defaulted move constructor of
std::pair<const Key, T> noexcept even if copying Key can throw. With these
compilers, std::vector already moves such elements itself when it grows,
and ordered_map correctly leaves growing to it.

The same misjudgement makes std::vector call std::terminate when a key copy
throws during growth, so the exception-safety test with throwing_key would
abort on these compilers as well.

Skip the static assertion and the exception-safety section when __EDG__ is
defined. Verified with icpc 2021.10 (-std=gnu++11) and nvc++ 25.5 (C++11 and
C++17) on Compiler Explorer: unit-ordered_map and unit-disabled_exceptions
build and pass.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:34 +02:00
Niels Lohmann d268eaa693 Convert floats with Eisel-Lemire when std::from_chars is unavailable (#5617)
* Convert floats with Eisel-Lemire when std::from_chars is unavailable

Float tokens that Clinger's fast path cannot convert (e.g. the 17-digit
coordinates of canada.json) went to strtod unless std::from_chars was
available. It is not used in C++11/14, and not with libc++, which does not
define __cpp_lib_to_chars. The Eisel-Lemire algorithm (after fast_float's
compute_float) now converts them with integer arithmetic, correctly rounded
for any token with at most 19 significant digits. Longer tokens are
truncated; the result is used if w and w + 1 round alike, else strtod
decides as before. Overflow still yields infinity (out_of_range.406).

The table of powers of five (fast_float's) lives in pow5_table.hpp; a unit
test recomputes every entry with big-integer arithmetic. Further tests:
known values generated with Python (whose float() is correctly rounded),
200,000 round trips through to_chars, and the 128-bit multiplication and
leading-zero count against big-integer references (both with and without a
128-bit type). Checked against strtod on 6.5 million tokens, among them
60,000 exact halfway cases: no difference.

json::parse on canada.json: -8.6% (C++11), -7.6% (C++17, Apple clang);
other files unchanged. Compile time of a TU including json.hpp: +0.7%.

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

* Fix CI: unused parse result and find() == npos in the Eisel-Lemire tests

GCC (-Werror=unused-result) rejected CHECK_THROWS_WITH_AS(json::parse(...))
because parse() is [[nodiscard]]; assign the result to a dummy json as the
other tests do. clang-tidy flagged longer.find('.') == npos with
abseil-string-find-str-contains; store the position in a variable first.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:26 +02:00
Niels Lohmann 5b9ffae8bb Move the float conversion chain out of the lexer (#5616)
lexer::convert_number() converted float tokens with std::from_chars (when
available), Clinger's fast path, and the locale-aware strtod fallback, all
as lexer members. They are now free functions in number_parse.hpp:

- convert_float_fast(): std::from_chars, then Clinger's fast path, skipped
  when the mantissa has too many significant digits
- convert_float_locale_aware(): strtof/strtod/strtold with the decimal point
  of the current locale, retried when the locale changed (#5198)

so that other code converting JSON number tokens gets the same values. No
change in behavior; the lexer no longer includes <clocale> and <cstdlib>.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:06:25 +02:00
Niels Lohmann 04f6ddd227 Keep external headers as #include when amalgamating (#5615)
A header that builds on json.hpp (such as the planned json_view.hpp) must
not inline json.hpp: its single-header version would contain a second copy
of the library, and that copy would change with every library change.

The optional config key "external" lists include paths that are kept as
#include directives. Only the first directive per path is kept; repeated
ones are commented out, as the tool already does for inlined headers.
config_json_view.json uses it for json_view.hpp; the existing configs do
not set it, and json.hpp and json_fwd.hpp regenerate byte-identically.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-30 20:05:51 +02:00
Niels Lohmann a2f45e7fbc Cache the release headers with functools.lru_cache
Codacy (Pylint) flagged the mutable default argument that header() used
as its cache. functools.lru_cache keeps the same memoization without it.
The script's output is unchanged.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 22:22:22 +02:00
Niels Lohmann 29a647a08b Correct documentation errors found while hunting for bugs
- patch/patch_inplace: list the JSON pointer errors parse_error.106-109
  and out_of_range.402/404, and quote the actual parse_error.105 message.
- unflatten: list parse_error.106/107/108 and out_of_range.404.
- to_bson: list out_of_range.415 (binary subtype above 255) and note
  that 412 and 415 are new in 3.13.0.
- to_string: state that string_t must be convertible to std::string, also
  in the StringType requirements table.
- JSON Lines: a `while (input >> j)` loop also throws after the last value
  for concatenated JSON values; show a loop that works for both.
- BON8: a string gets 0xFF only if nothing follows it in the message; a
  string at the end of an array or object is ended by 0xFE.
- custom_string_type.hpp: add operator+=(char), which the "Always
  required" list asks for (json_pointer::to_string, flatten, unflatten,
  and diff did not compile), and an ADL int_to_string for diff and items.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 19:50:03 +02:00
Niels Lohmann 8ee8bff661 Say the library is available as a single header and mention json_fwd.hpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 18:28:16 +02:00
Niels Lohmann 8ead67cc30 Correct the duplicate-key recipe's claim about SAX positions
The SAX interface's key() receives no position either; only parse_error()
does. Also note that the recipe does not report the path to the repeated
key (see discussion #5085).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 18:18:03 +02:00
Niels Lohmann aea2132069 Keep the customer links that could not be fixed
A dead link on the customers page is still the evidence of where the
use of the library was documented. Keep the original URLs of the entries
without a working replacement (Marne, Cisco Webex Desk Camera, Philips
Hue, CyberArk) and exclude exactly these URLs from the link check.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 17:37:30 +02:00
Niels Lohmann 526b6d3fd6 Review and extend the documentation, and check it in CI
A review of all documentation pages found factual errors, dead links,
missing cross-references, and gaps in examples. This fixes them and adds
checks so the same problems are caught automatically.

Fixes:
- wrong signatures and version histories (operator!= C++20 member,
  binary() subtype type, get<PointerType>(), JSON_NO_THREAD_LOCAL, ...)
- stale descriptions (number parsing since #5283, UBJSON table, SAX
  example that no longer compiled, tsl::ordered_map advice)
- dead internal and external links; repology.org badges (the domain is
  suspended) replaced by badges that query the registries directly
- deprecation notes link the migration guide; the guide itself fixed

Additions:
- "See also" sections, cross-references, 25 runnable examples, 12
  Mermaid diagrams, new API pages for json_pointer::operator<=> and
  byte_container_with_subtype::operator==/!=
- landing page, guides for untrusted input and performance
- "unreleased" badge after versions newer than the latest release

Checks:
- strict documentation build (broken links/anchors fail it); CI and
  the publish workflow fetch the full history the build needs
- weekly external link check, Mermaid syntax check in CI
- check_structure.py: example titles, heading levels, alt texts,
  header links, docset index coverage; its unused-example check works
  again
- all examples produce the same output on every platform

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 17:05:35 +02:00
Niels Lohmann 633de8e44b Fix CI: clang-tidy and GCC -Wnoexcept in the locale test (#5613)
#5597 was merged before all of its CI jobs had run, and two of them fail
on develop now, and so on every pull request:

- ci_clang_tidy: cert-err33-c for the two std::setlocale(LC_NUMERIC, "C")
  calls whose result was discarded. Check the result, like the other
  resets in the file.
- ci_test_standards_gcc (20) with GCC 16: -Wnoexcept for the two parser
  callbacks, which cannot throw but were not declared noexcept.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-28 22:20:43 +02:00
Niels Lohmann fc03b9912e Look up the locale decimal point at conversion time, not lexer construction (#5597)
* Look up the locale decimal point at conversion time, not lexer construction

The lexer read localeconv()->decimal_point once in its constructor and wrote
that character into token_buffer in place of '.'. The strtod fallback then
used the locale current at conversion time, so an LC_NUMERIC change in
between (parser callback, SAX handler, another thread) truncated the value
in release builds and fired the endptr assertion in debug builds.

token_buffer now always holds '.'. Only the strtof/strtod/strtold fallback
depends on the locale: it looks up the decimal point right before the call,
restores '.' afterwards, and repeats the conversion if the locale changed in
between. As a side effect, std::from_chars and Clinger's fast path now also
apply under locales whose decimal point is not '.'.

Fixes #5198

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

* Stop the strtod retry loop when the decimal point is unchanged

convert_float_locale_aware() repeated the conversion until strtod
consumed the whole token, assuming an early stop can only mean a locale
change. Under a locale whose decimal point is not a single character
(e.g. the two-byte U+066B of ar_EG.UTF-8, ar_SA.UTF-8, or fa_IR.UTF-8,
all available on macOS), the in-place substitution can never succeed,
so parsing any float that reaches the strtod fallback (for example
3.14159265358979323846 at C++11) hung forever. Before this branch, the
same input was truncated.

Retry only if the decimal point changed since the previous attempt;
otherwise keep the value strtod parsed so far, as before. Add a test
that parses such numbers under a multi-byte decimal point locale; it
hangs without this change.

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

* Fix -Weffc++ errors in the #5198 locale test

GCC's -Weffc++ (an error in ci_test_gcc and ci_test_standards_gcc)
rejected LocaleSwitchingSax: it has a pointer data member but does not
declare its copy operations, and its vectors are not initialized in the
member initializer list. Store the locale name as a std::string and give
the vectors brace initializers, like SaxEventLogger in
unit-deserialization.cpp.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-28 17:56:11 +02:00
Niels Lohmann 9e1a09eec0 Name the key type when rejecting non-string CBOR/MessagePack map keys (#5594)
* Name the key type when rejecting non-string CBOR/MessagePack map keys

CBOR and MessagePack allow map keys of any type, but JSON object keys
are always strings, so such maps are rejected. The error so far was the
one for a malformed string (e.g. "expected length specification
(0xA0-0xBF, 0xD9-0xDB); last byte: 0xC0" for a nil key), which does not
tell the user what went wrong. Report the type of the key instead:

  syntax error while parsing MessagePack object key: only string keys
  are supported, but found nil; last byte: 0xC0

The exception id (parse_error.113) and type are unchanged. Malformed
string keys and a missing key keep their previous messages. Document
the restriction on the CBOR and MessagePack pages.

Refs #2766, #3381

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

* Point the MessagePack key note to the spec's profile section

The note linked to "Serialization: type to format conversion", which says nothing about key types. Restricting map keys to strings is only mentioned in the "Profile" section (under "Future discussion") as an example of a JSON-compatible profile, so link there and describe it as such instead of as a permission.

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

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-28 17:51:07 +02:00
330 changed files with 10924 additions and 1257 deletions
+10
View File
@@ -142,6 +142,16 @@ The documentation will then be available at <http://127.0.0.1:8000/>. See the do
[mkdocs](https://www.mkdocs.org) and [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) for more
information.
Before opening a pull request, check the documentation like the CI does:
```shell
make build -C docs/mkdocs # strict build: fails on broken links, anchors, and structure problems
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; `make build` reports missing entries.
### Amalgamate the source code
The single-header files
+11
View File
@@ -18,6 +18,17 @@ updates:
cooldown:
default-days: 7
- package-ecosystem: npm
directory: /docs/mkdocs/scripts/mermaid
schedule:
interval: daily
cooldown:
default-days: 7
ignore:
# Material for MkDocs loads mermaid@11; keep the checker on the same major version
- dependency-name: mermaid
update-types: ["version-update:semver-major"]
- package-ecosystem: pip
directory: /tools/astyle
schedule:
+1
View File
@@ -67,6 +67,7 @@ jobs:
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s .
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.json -s .
cp include/nlohmann/json_literals.hpp $INCLUDE_DIR/json_literals.hpp
# the header list of the Bazel "json" target must match the files in include/
cmake -P cmake/scripts/gen_bazel_build_file.cmake
+46
View File
@@ -0,0 +1,46 @@
name: Check documentation links
# check the links of the documentation weekly; external links break without any change in this repository
on:
schedule:
- cron: '17 4 * * 1'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
jobs:
check_docs_links:
if: github.repository == 'nlohmann/json'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Harden Runner
uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
with:
egress-policy: audit
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install virtual environment
run: make install_venv -C docs/mkdocs
- name: Check links
shell: bash # adds -o pipefail, so tee does not hide the exit code
run: make link_check -C docs/mkdocs 2>&1 | tee link_check.log
- name: Summarize broken links
if: failure()
run: |
{
echo '### Broken documentation links'
echo '```'
grep 'invalid url' link_check.log || true
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
@@ -31,6 +31,10 @@ jobs:
egress-policy: audit
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# the git-revision-date-localized plugin needs the history for correct "last update" dates and so the
# strict build does not fail on a shallow clone
fetch-depth: 0
- name: Install virtual environment
run: make install_venv -C docs/mkdocs
+7 -1
View File
@@ -389,7 +389,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
target: [ci_test_examples, ci_test_build_documentation]
target: [ci_test_examples, ci_test_build_documentation, ci_test_documentation_mermaid]
steps:
- name: Harden Runner
uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
@@ -399,6 +399,12 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# the git-revision-date-localized plugin needs the history; a shallow clone makes the strict build fail
fetch-depth: ${{ matrix.target == 'ci_test_build_documentation' && '0' || '1' }}
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
if: matrix.target == 'ci_test_documentation_mermaid'
with:
node-version: 24
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
+2
View File
@@ -28,6 +28,8 @@
/docs/docset/docSet.dsidx
/docs/mkdocs/.cache/
/docs/mkdocs/docs/__pycache__/
/docs/mkdocs/hooks/__pycache__/
/docs/mkdocs/scripts/mermaid/node_modules/
/docs/mkdocs/site/
/docs/mkdocs/venv/
+3
View File
@@ -21,6 +21,7 @@ cc_library(
"include/nlohmann/adl_serializer.hpp",
"include/nlohmann/byte_container_with_subtype.hpp",
"include/nlohmann/detail/abi_macros.hpp",
"include/nlohmann/detail/bit_ops.hpp",
"include/nlohmann/detail/conversions/from_json.hpp",
"include/nlohmann/detail/conversions/to_chars.hpp",
"include/nlohmann/detail/conversions/to_json.hpp",
@@ -33,6 +34,7 @@ cc_library(
"include/nlohmann/detail/input/number_parse.hpp",
"include/nlohmann/detail/input/parser.hpp",
"include/nlohmann/detail/input/position_t.hpp",
"include/nlohmann/detail/input/pow5_table.hpp",
"include/nlohmann/detail/input/string_scan.hpp",
"include/nlohmann/detail/iterators/internal_iterator.hpp",
"include/nlohmann/detail/iterators/iter_impl.hpp",
@@ -65,6 +67,7 @@ cc_library(
"include/nlohmann/detail/value_t.hpp",
"include/nlohmann/json.hpp",
"include/nlohmann/json_fwd.hpp",
"include/nlohmann/json_literals.hpp",
"include/nlohmann/ordered_map.hpp",
"include/nlohmann/thirdparty/hedley/hedley.hpp",
"include/nlohmann/thirdparty/hedley/hedley_undef.hpp",
+16 -5
View File
@@ -21,6 +21,8 @@ TESTS_SRCS=$(shell find tests -type f \( -name '*.hpp' -o -name '*.cpp' -o -name
# the single headers (amalgamated from the source files)
AMALGAMATED_FILE=single_include/nlohmann/json.hpp
AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
# json_literals.hpp only includes <nlohmann/json.hpp>, so it is copied verbatim
AMALGAMATED_LITERALS_FILE=single_include/nlohmann/json_literals.hpp
##########################################################################
@@ -29,7 +31,7 @@ AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
# main target
all:
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd}.hpp from the include/nlohmann sources"
@echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd,_literals}.hpp from the include/nlohmann sources"
@echo "BUILD.bazel - regenerate the Bazel BUILD file from the include/nlohmann sources"
@echo "ChangeLog.md - generate ChangeLog file"
@echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date"
@@ -154,14 +156,14 @@ install_astyle:
# call the Artistic Style pretty printer on all source files
pretty: install_astyle
$(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) docs/mkdocs/docs/examples/*.cpp
$(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) docs/mkdocs/docs/examples/*.cpp
# call the Clang-Format on all source files
pretty_format:
for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/mkdocs/docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done
# create single header files and pretty print
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE)
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE)
$(MAKE) pretty
# call the amalgamation tool for json.hpp
@@ -172,16 +174,23 @@ $(AMALGAMATED_FILE): $(SRCS)
$(AMALGAMATED_FWD_FILE): $(SRCS)
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_fwd.json -s . --verbose=yes
# copy json_literals.hpp
$(AMALGAMATED_LITERALS_FILE): include/nlohmann/json_literals.hpp
cp include/nlohmann/json_literals.hpp $(AMALGAMATED_LITERALS_FILE)
# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources
# Note: this target is called by Travis
check-amalgamation:
@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~
@mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~
@mv $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~
@$(MAKE) amalgamate
@diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false)
@diff $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) ; false)
@diff $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE) ; false)
@mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE)
@mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE)
@mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE)
@mv BUILD.bazel BUILD.bazel~
@$(MAKE) BUILD.bazel
@diff BUILD.bazel BUILD.bazel~ || (echo "===================================================================\n BUILD.bazel is out of date! Please run 'make BUILD.bazel'.\n===================================================================" ; mv BUILD.bazel~ BUILD.bazel ; false)
@@ -222,7 +231,7 @@ json.tar.xz:
# We use `-X` to make the resulting ZIP file reproducible, see
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
include.zip: BUILD.bazel
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT
# Create the files for a release and add signatures and hashes.
release: include.zip json.tar.xz
@@ -231,10 +240,12 @@ release: include.zip json.tar.xz
gpg --armor --detach-sig include.zip
gpg --armor --detach-sig $(AMALGAMATED_FILE)
gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE)
gpg --armor --detach-sig $(AMALGAMATED_LITERALS_FILE)
gpg --armor --detach-sig json.tar.xz
cp $(AMALGAMATED_FILE) release_files
cp $(AMALGAMATED_FWD_FILE) release_files
mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc 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
cd release_files ; shasum -a 256 json.hpp include.zip json.tar.xz > hashes.txt
+1 -1
View File
@@ -13,7 +13,6 @@
[![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://json.nlohmann.me)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/develop/LICENSE.MIT)
[![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases)
[![Packaging status](https://repology.org/badge/tiny-repos/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions)
[![GitHub Downloads](https://img.shields.io/github/downloads/nlohmann/json/total)](https://github.com/nlohmann/json/releases)
[![GitHub Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](https://github.com/nlohmann/json/issues)
[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/nlohmann/json.svg)](https://isitmaintained.com/project/nlohmann/json "Average time to resolve an issue")
@@ -1395,6 +1394,7 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I
- 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 copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
- The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
- The class contains an adapted version of the Eisel-Lemire algorithm and its table of powers of five from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright &copy; 2021 The fast_float authors
<img align="right" src="https://git.fsfe.org/reuse/reuse-ci/raw/branch/master/reuse-horizontal.png" alt="REUSE Software">
+10 -1
View File
@@ -373,9 +373,10 @@ file(GLOB_RECURSE INDENT_FILES
set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann)
set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate)
add_custom_target(ci_test_amalgamation
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~
COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~
COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~
COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~
COMMAND cp ${include_dir}/json_literals.hpp ${include_dir}/json_literals.hpp~
COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle
COMMAND venv_astyle/bin/pip3 --quiet install -r ${CMAKE_SOURCE_DIR}/tools/astyle/requirements.txt
@@ -383,10 +384,12 @@ add_custom_target(ci_test_amalgamation
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s .
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s .
COMMAND cp ${PROJECT_SOURCE_DIR}/include/nlohmann/json_literals.hpp ${include_dir}/json_literals.hpp
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp
COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp
COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp
COMMAND diff ${include_dir}/json_literals.hpp~ ${include_dir}/json_literals.hpp
COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES}
COMMAND for FILE in `find . -name '*.orig'`\; do false \; done
@@ -849,6 +852,12 @@ add_custom_target(ci_test_build_documentation
COMMENT "Build the documentation"
)
add_custom_target(ci_test_documentation_mermaid
COMMAND make check_mermaid
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs/mkdocs
COMMENT "Check the Mermaid diagrams of the documentation"
)
###############################################################################
# Clean up all generated files.
###############################################################################
+3 -2
View File
@@ -35,9 +35,10 @@ create_output: $(EXAMPLES:.cpp=.output)
# check output of all stand-alone example files
check_output: $(EXAMPLES:.cpp=.test)
# check output of all stand-alone example files (exclude files with platform-dependent output.)
# check output of all stand-alone example files (exclude files whose output depends on the platform by nature:
# library and compiler information, container size limits, and hash values)
# This target is used in the CI (ci_test_documentation).
check_output_portable: $(filter-out mkdocs/docs/examples/meta.test mkdocs/docs/examples/max_size.test mkdocs/docs/examples/std_hash.test mkdocs/docs/examples/basic_json__CompatibleType.test,$(EXAMPLES:.cpp=.test))
check_output_portable: $(filter-out mkdocs/docs/examples/meta.test mkdocs/docs/examples/max_size.test mkdocs/docs/examples/std_hash.test,$(EXAMPLES:.cpp=.test))
clean:
rm -fr $(EXAMPLES:.cpp=)
+36
View File
@@ -10,9 +10,12 @@ INSERT INTO searchIndex(name, type, path) VALUES ('byte_container_with_subtype',
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');
@@ -132,15 +135,19 @@ INSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/ind
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');
@@ -163,6 +170,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('operator<<', 'Operator', 'api
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');
@@ -195,17 +203,20 @@ INSERT INTO searchIndex(name, type, path) VALUES ('nlohmann Namespace', 'Guide',
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_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');
@@ -214,34 +225,59 @@ INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_11', 'Macro', 'a
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_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_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');
+12 -1
View File
@@ -1,3 +1,8 @@
# The MkDocs 2.0 banners of Material for MkDocs and ProperDocs (via mkdocs-redirects) are printed to stderr, not
# logged, so they do not affect --strict; silence them anyway.
export NO_MKDOCS_2_WARNING := true
export DISABLE_MKDOCS_2_WARNING := true
# serve the site locally
serve: style_check
venv/bin/mkdocs serve
@@ -8,11 +13,17 @@ serve_dirty: style_check
# This target is used in the CI (ci_test_build_documentation).
# This target is used by the docset Makefile.
build: style_check
venv/bin/mkdocs build
venv/bin/mkdocs build --strict
style_check:
@cd docs ; ../venv/bin/python3 ../scripts/check_structure.py
# check that all Mermaid diagrams parse (needs Node.js)
# This target is used in the CI (ci_test_documentation_mermaid).
check_mermaid:
npm ci --prefix scripts/mermaid --ignore-scripts --no-audit --no-fund
node scripts/mermaid/check_mermaid.mjs docs
# check the links in the documentation files in docs/mkdocs
link_check:
ENABLED_HTMLPROOFER=true venv/bin/mkdocs build
+18 -1
View File
@@ -96,7 +96,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
## Examples
??? example
??? example "Example: (1) reading from a string"
The example below demonstrates the `accept()` function reading from a string.
@@ -110,6 +110,21 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/accept__string.output"
```
??? example "Example: (2) reading from an iterator pair"
The example below demonstrates the `accept()` function reading from an iterator pair. Only the first call covers
exactly the JSON text; the second one also covers the trailing bytes and is therefore rejected.
```cpp
--8<-- "examples/accept__iterator_pair.cpp"
```
Output:
```json
--8<-- "examples/accept__iterator_pair.output"
```
## See also
- [parse](parse.md) - deserialize from a compatible input
@@ -137,3 +152,5 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#parsing) for how to update existing code.
+10 -3
View File
@@ -25,7 +25,7 @@ To store objects in C++, a type is defined by the template parameters explained
## Notes
#### Default type
### Default type
With the default values for `ArrayType` (`std::vector`) and `AllocatorType` (`std::allocator`), the default value for
`array_t` is:
@@ -37,7 +37,7 @@ std::vector<
>
```
#### Limits
### Limits
[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the maximum depth of nesting.
@@ -46,7 +46,7 @@ In this class, the array's limit of nesting is not explicitly constrained. Howev
introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the
[`max_size`](max_size.md) function of a JSON array.
#### Storage
### Storage
Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type
`#!cpp array_t*` must be dereferenced.
@@ -67,6 +67,13 @@ Arrays are stored as pointers in a `basic_json` type. That is, for any access to
--8<-- "examples/array_t.output"
```
## See also
- [object_t](object_t.md) the type used to store JSON objects
- [binary_t](binary_t.md) the type used to store binary values
- [is_array](is_array.md) checks whether the JSON value is an array
- [max_size](max_size.md) returns the maximum possible number of elements
## Version history
- Added in version 1.0.0.
+14
View File
@@ -92,6 +92,20 @@ Strong exception safety: if an exception occurs, the original value stays intact
3. Logarithmic in the size of the container.
4. Logarithmic in the size of the container.
## Notes
!!! warning "Deprecation"
Overload (4) also accepts a [`json_pointer`](../json_pointer/index.md) whose template argument is a `basic_json`
specialization (e.g., `nlohmann::json_pointer<nlohmann::json>`) instead of a string type. This is deprecated since
version 3.11.0 and will be removed in a future major version; use `basic_json::json_pointer` (for `json`,
`nlohmann::json_pointer<std::string>`) instead.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#json-pointers) for how to update existing code.
## Examples
??? example "Example: (1) access specified array element with bounds checking"
+53 -7
View File
@@ -99,6 +99,25 @@ basic_json(basic_json&& other) noexcept;
elements of the pairs are treated as keys and the second elements are as values.
3. In all other cases, an array is created.
The following flowchart also takes into account what happens when `type_deduction` is `#!cpp false`, in which case
`manual_type` decides between object and array, and an object can only be forced if `init` actually matches rule 2
(or is empty):
```mermaid
flowchart TD
A(["initializer_list init"]) --> B{"empty, or every element is a 2-element<br/>array whose first element is a string?"}
B -->|"yes"| C{"type_deduction"}
B -->|"no"| D{"type_deduction"}
C -->|"true"| OBJ["create object"]
C -->|"false"| E{"manual_type"}
E -->|"object"| OBJ
E -->|"array"| ARR["create array"]
D -->|"true"| ARR
D -->|"false"| F{"manual_type"}
F -->|"array"| ARR
F -->|"object"| ERR["throw type_error.301"]
```
The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:
1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object.
@@ -139,8 +158,8 @@ basic_json(basic_json&& other) noexcept;
- In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206)
is thrown.
- In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be
`end()`. In this case, the value is copied. Otherwise,
- In case of other primitive types (number, boolean, string, or binary), `first` must be `begin()` and `last`
must be `end()`. In this case, the value is copied. Otherwise,
[`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown.
- In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or
`std::map`; that is, a JSON array or object is constructed from the values in the range.
@@ -169,8 +188,8 @@ basic_json(basic_json&& other) noexcept;
- `BasicJsonType` has different template arguments than `basic_json_t`.
**Note:** For cross-`basic_json` conversions to produce correct results, the target `basic_json`'s
`object_t::key_type` and `string_t` must be directly constructible from the source `basic_json`'s
corresponding types. See the description of overload (4) above for details on what happens when
[`object_t`](object_t.md)`::key_type` and [`string_t`](string_t.md) must be directly constructible from the source
`basic_json`'s corresponding types. See the description of overload (4) above for details on what happens when
this requirement is not met.
`U`:
@@ -242,8 +261,8 @@ basic_json(basic_json&& other) noexcept;
and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range
`[first, last)` is undefined.
- Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first`
and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first
element anymore. In this case, the range `[first, last)` is undefined. See the example code below.
and `last` belong to a primitive type (number, boolean, string, or binary), but `first` does not point to the
first element anymore. In this case, the range `[first, last)` is undefined. See the example code below.
- Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first`
and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined.
8. (none)
@@ -345,6 +364,22 @@ basic_json(basic_json&& other) noexcept;
Note the output is platform-dependent.
??? example "Example: (4) create a JSON value from another `basic_json` specialization"
The example below shows how a `json` value is converted to an `ordered_json` value and back using the converting
constructor. Note how the original insertion order of `oj` is not restored, because it was already given up when
converting to `json`, whose `object_t` sorts by key.
```cpp
--8<-- "examples/basic_json__BasicJsonType.cpp"
```
Output:
```json
--8<-- "examples/basic_json__BasicJsonType.output"
```
??? example "Example: (5) create a container (array or object) from an initializer list"
The example below shows how JSON values are created from initializer lists.
@@ -415,6 +450,15 @@ basic_json(basic_json&& other) noexcept;
--8<-- "examples/basic_json__moveconstructor.output"
```
## See also
- [array](array.md) create a JSON array value, forcing array creation from an initializer list even when it looks like
an object
- [object](object.md) create a JSON object value, forcing object creation from an initializer list
- [binary](binary.md) create a JSON binary array value
- [operator=](operator=.md) copy assignment operator
- [Creating JSON values](../../features/creating_values.md) - the article on creating JSON values
## Version history
1. Since version 1.0.0.
@@ -423,6 +467,8 @@ basic_json(basic_json&& other) noexcept;
4. Since version 3.2.0.
5. Since version 1.0.0.
6. Since version 1.0.0.
7. Since version 1.0.0.
7. Since version 1.0.0. Fixed in version 3.13.0 to also check the iterator range for binary values; before, a range
that did not cover the whole value (such as `(end(), end())`) was accepted and the whole binary value was copied,
unlike the other primitive types.
8. Since version 1.0.0.
9. Since version 1.0.0.
+8
View File
@@ -37,6 +37,14 @@ Constant.
--8<-- "examples/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
- [rbegin](rbegin.md) returns a reverse iterator to the last element
- [items](items.md) returns an iteration proxy to access keys and values during range-based for loops
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
+11 -2
View File
@@ -7,9 +7,9 @@ static basic_json binary(typename binary_t::container_type&& init);
// (2)
static basic_json binary(const typename binary_t::container_type& init,
std::uint8_t subtype);
typename binary_t::subtype_type subtype);
static basic_json binary(typename binary_t::container_type&& init,
std::uint8_t subtype);
typename binary_t::subtype_type subtype);
```
1. Creates a JSON binary array value from a given binary container.
@@ -61,6 +61,15 @@ initialization of a binary array type, for backwards compatibility and so it doe
--8<-- "examples/binary.output"
```
## See also
- [binary_t](binary_t.md) type for binary values
- [get_binary](get_binary.md) get a reference to the stored binary value
- [is_binary](is_binary.md) return whether the value is binary
- [byte_container_with_subtype](../byte_container_with_subtype/index.md) container for binary values with subtype
- [Binary Values](../../features/binary_values.md) - the article on binary values
## Version history
- Added in version 3.8.0.
- Changed the type of `subtype` from `std::uint8_t` to `binary_t::subtype_type` (`std::uint64_t`) in version 3.10.0.
+5 -5
View File
@@ -48,16 +48,16 @@ represent a byte array in modern C++.
## Notes
#### Default type
### Default type
The default values for `BinaryType` is `#!cpp std::vector<std::uint8_t>`.
#### Supported byte types
### Supported byte types
`#!cpp std::vector<std::uint8_t>`, `#!cpp std::vector<char>`, and `#!cpp std::vector<std::byte>` are supported.
Regardless of which of them is configured, [`dump`](dump.md) writes the bytes as the numbers 0..255.
#### Custom BinaryType behavior
### Custom BinaryType behavior
When a custom `BinaryType` is configured (other than the default `#!cpp std::vector<std::uint8_t>`), you can assign
values of that type directly to a `basic_json` instance, and they will automatically be recognized as binary values
@@ -89,12 +89,12 @@ assert(extracted == data);
This automatic type detection is a convenience feature that only applies to custom (non-default) `BinaryType` configurations.
The default `nlohmann::json` continues to treat `#!cpp std::vector<std::uint8_t>` as arrays for backward compatibility.
#### Storage
### Storage
Binary Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of the
type `#!cpp binary_t*` must be dereferenced.
#### Notes on subtypes
### Notes on subtypes
- CBOR
- Binary values are represented as byte strings. Subtypes are written as tags.
+6 -2
View File
@@ -21,11 +21,11 @@ To store boolean values in C++, a type is defined by the template parameter `Bo
## Notes
#### Default type
### Default type
With the default values for `BooleanType` (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`.
#### Storage
### Storage
Boolean values are stored directly inside a `basic_json` type.
@@ -45,6 +45,10 @@ Boolean values are stored directly inside a `basic_json` type.
--8<-- "examples/boolean_t.output"
```
## See also
- [is_boolean](is_boolean.md) checks whether the JSON value is a boolean
## Version history
- Added in version 1.0.0.
@@ -36,6 +36,13 @@ Constant.
--8<-- "examples/cbegin.output"
```
## See also
- [begin](begin.md) returns an iterator to the first element
- [cend](cend.md) returns a const iterator to one past the last element
- [crbegin](crbegin.md) returns a const reverse iterator to the last element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
@@ -38,6 +38,12 @@ store
--8<-- "examples/cbor_tag_handler_t.output"
```
## See also
- [from_cbor](from_cbor.md) deserializes a JSON value from CBOR
- [input_format_t](input_format_t.md) the enumeration of supported input formats
- [CBOR](../../features/binary_formats/cbor.md) - the article on the CBOR format
## Version history
- Added in version 3.9.0. Added value `store` in 3.10.0.
+7
View File
@@ -36,6 +36,13 @@ Constant.
--8<-- "examples/cend.output"
```
## See also
- [end](end.md) returns an iterator to one past the last element
- [cbegin](cbegin.md) returns a const iterator to the first element
- [crend](crend.md) returns a const reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
+15 -9
View File
@@ -7,15 +7,15 @@ void clear() noexcept;
Clears the content of a JSON value and resets it to the default value as if [`basic_json(value_t)`](basic_json.md) would
have been called with the current value type from [`type()`](type.md):
| Value type | initial value |
|------------|----------------------|
| null | `null` |
| boolean | `false` |
| string | `""` |
| number | `0` |
| binary | An empty byte vector |
| object | `{}` |
| array | `[]` |
| Value type | initial value |
|------------|-----------------------------------------|
| null | `null` |
| boolean | `false` |
| string | `""` |
| number | `0` |
| binary | An empty byte vector with no subtype |
| object | `{}` |
| array | `[]` |
Has the same effect as calling
@@ -52,7 +52,13 @@ All iterators, pointers, and references related to this container are invalidate
--8<-- "examples/clear.output"
```
## See also
- [erase](erase.md) removes elements from a JSON value
- [empty](empty.md) checks whether the JSON value has no elements
## Version history
- Added in version 1.0.0.
- Added support for binary types in version 3.8.0.
- Fixed in version 3.13.0 to also clear the subtype of a binary value; before, the subtype was left unchanged.
@@ -58,11 +58,27 @@ Logarithmic in the size of the JSON object.
- This method always returns `#!cpp false` when executed on a JSON type that is not an object.
- This method can be executed on any JSON value type.
- Calling this function with an integer argument (for example, `#!cpp contains(0)`) does not compile: such an argument
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
constructing a `#!cpp std::string` for the object key. To check for an array element instead, use [`at`](at.md),
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
!!! info "Postconditions"
If `#!cpp j.contains(x)` returns `#!c true` for a key or JSON pointer `x`, then it is safe to call `j[x]`.
!!! warning "Deprecation"
Overload (3) also accepts a [`json_pointer`](../json_pointer/index.md) whose template argument is a `basic_json`
specialization (e.g., `nlohmann::json_pointer<nlohmann::json>`) instead of a string type. This is deprecated since
version 3.11.0 and will be removed in a future major version; use `basic_json::json_pointer` (for `json`,
`nlohmann::json_pointer<std::string>`) instead.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#json-pointers) for how to update existing code.
## Examples
??? example "Example: (1) check with key"
@@ -117,3 +133,5 @@ Logarithmic in the size of the JSON object.
1. Added in version 3.11.0.
2. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0.
3. Added in version 3.7.0.
4. Deleted overloads for integral key types added in version 3.13.0 to reject such calls at compile time instead of
causing undefined behavior at runtime.
+7 -1
View File
@@ -40,7 +40,11 @@ Logarithmic in the size of the JSON object.
## Notes
This method always returns `0` when executed on a JSON type that is not an object.
- This method always returns `0` when executed on a JSON type that is not an object.
- Calling this function with an integer argument (for example, `#!cpp count(0)`) does not compile: such an argument
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
constructing a `#!cpp std::string` for the object key. To check for an array element instead, use [`at`](at.md),
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
## Examples
@@ -81,3 +85,5 @@ This method always returns `0` when executed on a JSON type that is not an objec
1. Added in version 3.11.0.
2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0.
3. Deleted overload for integral key types added in version 3.13.0 to reject such calls at compile time instead of
causing undefined behavior at runtime.
@@ -36,6 +36,13 @@ Constant.
--8<-- "examples/crbegin.output"
```
## See also
- [crend](crend.md) returns a const reverse iterator to one before the first element
- [rbegin](rbegin.md) returns a reverse iterator to the last element
- [cbegin](cbegin.md) returns a const iterator to the first element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
+7
View File
@@ -37,6 +37,13 @@ Constant.
--8<-- "examples/crend.output"
```
## See also
- [crbegin](crbegin.md) returns a const reverse iterator to the last element
- [rend](rend.md) returns a reverse iterator to one before the first element
- [cend](cend.md) returns a const iterator to one past the last element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
@@ -30,6 +30,11 @@ The actual comparator used depends on [`object_t`](object_t.md) and can be obtai
--8<-- "examples/default_object_comparator_t.output"
```
## See also
- [object_comparator_t](object_comparator_t.md) the comparator actually used by `object_t`
- [object_t](object_t.md) the type used to store JSON objects
## Version history
- Added in version 3.11.0.
+2 -1
View File
@@ -31,7 +31,8 @@ a `#!cpp bool` denoting whether the insertion took place.
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a `#!json null`
value is converted to an empty object before the element is added and keeps that type if adding the element throws.
## Exceptions
@@ -28,6 +28,11 @@ iterator is invalidated.
reference to the inserted element
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a `#!json null`
value is converted to an empty array before the element is added and keeps that type if adding the element throws.
## Exceptions
Throws [`type_error.311`](../../home/exceptions.md#jsonexceptiontype_error311) when called on a type other than JSON
+5
View File
@@ -60,6 +60,11 @@ itself is empty which is `#!cpp false` in the case of a string.
--8<-- "examples/empty.output"
```
## See also
- [size](size.md) returns the number of elements
- [clear](clear.md) clears the content and resets the value to the default value
## Version history
- Added in version 1.0.0.
+7
View File
@@ -37,6 +37,13 @@ Constant.
--8<-- "examples/end.output"
```
## See also
- [begin](begin.md) returns an iterator to the first element
- [cend](cend.md) returns a const iterator to one past the last element
- [rend](rend.md) returns a reverse iterator to one before the first element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
@@ -37,6 +37,11 @@ ignore
--8<-- "examples/error_handler_t.output"
```
## See also
- [dump](dump.md) serializes a JSON value, with an `error_handler_t` parameter to configure invalid UTF-8 handling
- [Handling invalid UTF-8](../../features/serialization.md#handling-invalid-utf-8) - the article on handling invalid UTF-8
## Version history
- Added in version 3.4.0.
+7 -1
View File
@@ -44,7 +44,11 @@ Logarithmic in the size of the JSON object.
## Notes
This method always returns `end()` when executed on a JSON type that is not an object.
- This method always returns `end()` when executed on a JSON type that is not an object.
- Calling this function with an integer argument (for example, `#!cpp find(0)`) does not compile: such an argument
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
constructing a `#!cpp std::string` for the object key. To access an array element instead, use [`at`](at.md),
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
## Examples
@@ -85,3 +89,5 @@ This method always returns `end()` when executed on a JSON type that is not an o
1. Added in version 3.11.0.
2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.
3. Deleted overloads for integral key types added in version 3.13.0 to reject such calls at compile time instead of
causing undefined behavior at runtime.
+16 -1
View File
@@ -27,7 +27,7 @@ Empty objects and arrays are flattened to `#!json null` and will not be reconstr
## Examples
??? example
??? example "Example: flatten a JSON object"
The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers.
@@ -41,6 +41,21 @@ Empty objects and arrays are flattened to `#!json null` and will not be reconstr
--8<-- "examples/flatten.output"
```
??? example "Example: empty objects and arrays are flattened to `#!json null`"
The following code shows that an empty object and an empty array are both flattened to `#!json null`, and that
`unflatten()` restores them as `#!json null` rather than as empty containers.
```cpp
--8<-- "examples/flatten__empty.cpp"
```
Output:
```json
--8<-- "examples/flatten__empty.output"
```
## See also
- [unflatten](unflatten.md) the reverse function
@@ -123,3 +123,5 @@ Linear in the size of the input.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#parsing) for how to update existing code.
+4 -2
View File
@@ -80,8 +80,8 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
the end of the file was not reached when `strict` was set to true
- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from CBOR were
used in the given input or if the input is not valid CBOR
- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as a map key,
but not found
- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a map key is not a string (keys of other
types are not supported, as JSON object keys are always strings) or a string is malformed
## Complexity
@@ -133,3 +133,5 @@ Linear in the size of the input.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#parsing) for how to update existing code.
@@ -73,8 +73,8 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
the end of the file was not reached when `strict` was set to true
- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from
MessagePack were used in the given input or if the input is not valid MessagePack
- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as a map key,
but not found
- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a map key is not a string (keys of other
types are not supported, as JSON object keys are always strings) or a string is malformed
## Complexity
@@ -125,3 +125,5 @@ Linear in the size of the input.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#parsing) for how to update existing code.
@@ -124,3 +124,5 @@ Linear in the size of the input.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#parsing) for how to update existing code.
+26 -6
View File
@@ -13,16 +13,16 @@ BasicJsonType get() const;
// (3)
template<typename PointerType>
PointerType get_ptr();
PointerType get() noexcept;
template<typename PointerType>
constexpr const PointerType get_ptr() const noexcept;
const PointerType get() const noexcept; // constexpr since C++14
```
1. Explicit type conversion between the JSON value and a compatible value which is
[CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and
[DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). The value is converted by
calling the `json_serializer<ValueType>` `from_json()` method.
calling the [`json_serializer<ValueType>`](json_serializer.md) `from_json()` method.
The function is equivalent to executing
```cpp
@@ -84,6 +84,12 @@ constexpr const PointerType get_ptr() const noexcept;
3. pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `#!cpp nullptr`
otherwise
## Exception safety
Depends on what `json_serializer<ValueType>` `from_json()` method throws for overloads (1) and (2); the JSON value
itself is never modified, since `get()` is a `#!cpp const` member function. No-throw guarantee for overload (3): this
function never throws exceptions.
## Exceptions
Depends on what `json_serializer<ValueType>` `from_json()` method throws
@@ -123,13 +129,13 @@ overload (3).
## Examples
??? example
??? example "Example: (1) explicit conversion to compatible types"
The example below shows several conversions from JSON values
to other types. There a few things to note: (1) Floating-point numbers can
be converted to integers, (2) A JSON array can be converted to a standard
`std::vector<short>`, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string, json>`.
associative containers such as `std::map<std::string, json>`.
```cpp
--8<-- "examples/get__ValueType_const.cpp"
@@ -141,7 +147,21 @@ overload (3).
--8<-- "examples/get__ValueType_const.output"
```
??? example
??? example "Example: (2) explicit conversion to another `basic_json` specialization"
The example below shows how a `json` value is converted to an `ordered_json` value using `get<BasicJsonType>()`.
```cpp
--8<-- "examples/get__BasicJsonType.cpp"
```
Output:
```json
--8<-- "examples/get__BasicJsonType.output"
```
??? example "Example: (3) explicit pointer access to the stored value"
The example below shows how pointers to internal values of a JSON value can be requested. Note that no type
conversions are made and a `#cpp nullptr` is returned if the value and the requested pointer type does not match.
@@ -10,6 +10,14 @@ Returns the allocator associated with the container.
associated allocator
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
## Complexity
Constant.
## Examples
??? example
@@ -26,6 +34,11 @@ associated allocator
--8<-- "examples/get_allocator.output"
```
## See also
- [basic_json](index.md#template-parameters) the class template, with `AllocatorType` as one of its template parameters
- [Template Parameter Requirements](../../features/types/template_parameters.md#allocatortype) - the requirements for `AllocatorType`
## Version history
- Added in version 1.0.0.
+7 -2
View File
@@ -8,7 +8,7 @@ ValueType& get_to(ValueType& v) const noexcept(
```
Explicit type conversion between the JSON value and a compatible value. The value is filled into the input parameter by
calling the `json_serializer<ValueType>` `from_json()` method.
calling the [`json_serializer<ValueType>`](json_serializer.md) `from_json()` method.
The function is equivalent to executing
```cpp
@@ -34,6 +34,11 @@ the compiler reports that no matching `get_to` was found.
the input parameter, allowing chaining calls
## Exception safety
Depends on what `json_serializer<ValueType>` `from_json()` method throws; the JSON value itself is never modified,
since `get_to()` is a `#!cpp const` member function.
## Exceptions
Depends on what `json_serializer<ValueType>` `from_json()` method throws
@@ -49,7 +54,7 @@ Depends on the `json_serializer<ValueType>::from_json()` implementation.
The example below shows several conversions from JSON values to other types. There a few things to note: (1)
Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard
`#!cpp std::vector<short>`, (3) A JSON object can be converted to C++ associative containers such as
`#cpp std::unordered_map<std::string, json>`.
`#!cpp std::map<std::string, json>`.
```cpp
--8<-- "examples/get_to.cpp"
@@ -51,6 +51,11 @@ bon8
--8<-- "examples/sax_parse__binary.output"
```
## See also
- [sax_parse](sax_parse.md) generic SAX parse interface, taking an `input_format_t` to select the input format
- [cbor_tag_handler_t](cbor_tag_handler_t.md) configures how CBOR tags are treated while parsing
## Version history
- Added in version 3.2.0.
+9 -7
View File
@@ -109,11 +109,11 @@ Strong exception safety: if an exception occurs, the original value stays intact
2. Linear in `cnt` plus linear in the distance between `pos` and end of the container.
3. Linear in `#!cpp std::distance(first, last)` plus linear in the distance between `pos` and end of the container.
4. Linear in `ilist.size()` plus linear in the distance between `pos` and end of the container.
5. Logarithmic: `O(N*log(size() + N))`, where `N` is the number of elements to insert.
5. `O(N*log(size() + N))`, where `N` is the number of elements to insert.
## Examples
??? example "Example (1): insert element into array"
??? example "Example: (1) insert element into array"
The example shows how `insert()` is used.
@@ -127,7 +127,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
--8<-- "examples/insert.output"
```
??? example "Example (2): insert copies of element into array"
??? example "Example: (2) insert copies of element into array"
The example shows how `insert()` is used.
@@ -141,7 +141,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
--8<-- "examples/insert__count.output"
```
??? example "Example (3): insert a range of elements into an array"
??? example "Example: (3) insert a range of elements into an array"
The example shows how `insert()` is used.
@@ -155,7 +155,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
--8<-- "examples/insert__range.output"
```
??? example "Example (4): insert elements from an initializer list into an array"
??? example "Example: (4) insert elements from an initializer list into an array"
The example shows how `insert()` is used.
@@ -169,7 +169,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
--8<-- "examples/insert__ilist.output"
```
??? example "Example (5): insert a range of elements into an object"
??? example "Example: (5) insert a range of elements into an object"
The example shows how `insert()` is used.
@@ -195,5 +195,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
1. Added in version 1.0.0.
2. Added in version 1.0.0.
3. Added in version 1.0.0.
4. Added in version 1.0.0.
4. Added in version 1.0.0. Fixed in version 3.13.0 to copy the values before inserting; before, an `ilist` that
referred to elements of the array being inserted into could insert wrong values, because the range insert could
move from or shift an element before it was copied.
5. Added in version 3.0.0.
@@ -34,6 +34,13 @@ Constant.
--8<-- "examples/is_array.output"
```
## See also
- [is_object](is_object.md) checks whether the JSON value is an object
- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object)
- [type](type.md) returns the type of the JSON value
- [array_t](array_t.md) the type used to store JSON arrays
## Version history
- Added in version 1.0.0.
@@ -34,6 +34,12 @@ Constant.
--8<-- "examples/is_binary.output"
```
## See also
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive
- [binary_t](binary_t.md) the type used to store binary values
- [get_binary](get_binary.md) returns a reference to the stored binary value
## Version history
- Added in version 3.8.0.
@@ -34,6 +34,11 @@ Constant.
--8<-- "examples/is_boolean.output"
```
## See also
- [boolean_t](boolean_t.md) the type used to store JSON booleans
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive
## Version history
- Added in version 1.0.0.
@@ -55,7 +55,7 @@ with `allow_exceptions` set to `#!cpp false`: a parse error then yields a discar
## Examples
??? example
??? example "Example: `is_discarded()` for ordinary JSON values"
The following code exemplifies `is_discarded()` for all JSON types.
@@ -69,6 +69,22 @@ with `allow_exceptions` set to `#!cpp false`: a parse error then yields a discar
--8<-- "examples/is_discarded.output"
```
??? example "Example: discarded values from parsing"
The following code shows the two situations in which a discarded value can be observed: parsing invalid JSON with
`allow_exceptions` set to `#!cpp false`, and a parser callback that discards the top-level value (which is replaced
by `#!json null` and therefore does *not* remain discarded).
```cpp
--8<-- "examples/is_discarded__parse.cpp"
```
Output:
```json
--8<-- "examples/is_discarded__parse.output"
```
## Version history
- Added in version 1.0.0.
@@ -34,6 +34,13 @@ Constant.
--8<-- "examples/is_null.output"
```
## See also
- [is_array](is_array.md) checks whether the JSON value is an array
- [is_object](is_object.md) checks whether the JSON value is an object
- [type](type.md) returns the type of the JSON value
- [value_t](value_t.md) the enumeration of JSON types
## Version history
- Added in version 1.0.0.
@@ -34,6 +34,13 @@ Constant.
--8<-- "examples/is_object.output"
```
## See also
- [is_array](is_array.md) checks whether the JSON value is an array
- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object)
- [type](type.md) returns the type of the JSON value
- [object_t](object_t.md) the type used to store JSON objects
## Version history
- Added in version 1.0.0.
@@ -34,6 +34,12 @@ Constant.
--8<-- "examples/is_string.output"
```
## See also
- [is_primitive](is_primitive.md) checks whether the JSON value is primitive
- [type](type.md) returns the type of the JSON value
- [string_t](string_t.md) the type used to store JSON strings
## Version history
- Added in version 1.0.0.
+2
View File
@@ -114,3 +114,5 @@ When iterating over an array, `key()` will return the index of the element as st
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#miscellaneous-functions) for how to update existing code.
@@ -14,12 +14,12 @@ Examples of such functionality might be metadata, additional member functions (e
## Notes
#### Default type
### Default type
The default value for `CustomBaseClass` is `void`. In this case, an
[empty base class](https://en.cppreference.com/w/cpp/language/ebo) is used and no additional functionality is injected.
#### Limitations
### Limitations
The type `CustomBaseClass` has to be a default-constructible, non-`final` class.
`basic_json` only supports copy/move construction/assignment if `CustomBaseClass` does so as well.
@@ -43,6 +43,10 @@ A `CustomBaseClass` with non-static data members forfeits `basic_json`'s
--8<-- "examples/json_base_class_t.output"
```
## See also
- [Template Parameter Requirements](../../features/types/template_parameters.md#custombaseclass) - the requirements for `CustomBaseClass`
## Version history
- Added in version 3.12.0.
@@ -15,11 +15,11 @@ using json_serializer = JSONSerializer<T, SFINAE>;
## Notes
#### Default type
### Default type
The default values for `json_serializer` is [`adl_serializer`](../adl_serializer/index.md).
#### Requirements
### Requirements
A custom serializer must provide `#!cpp static void to_json(basic_json&, T)` for every type it serializes, and either
`#!cpp static void from_json(const basic_json&, T&)` or `#!cpp static T from_json(const basic_json&)` for every type it
@@ -42,6 +42,13 @@ deserializes. See [Template Parameter Requirements](../../features/types/templat
--8<-- "examples/from_json__non_default_constructible.output"
```
## See also
- [adl_serializer](../adl_serializer/index.md) the default `json_serializer`
- [get](get.md) explicit type conversion using the `json_serializer`'s `from_json()` method
- [get_to](get_to.md) explicit type conversion into a variable using the `json_serializer`'s `from_json()` method
- [Arbitrary Type Conversions](../../features/arbitrary_types.md) - the article on converting between JSON values and arbitrary types
## Version history
- Since version 2.0.0.
@@ -54,6 +54,12 @@ string elements the JSON value can store which is `1`.
Note the output is platform-dependent.
## See also
- [size](size.md) returns the number of elements
- [array_t](array_t.md) the type used to store JSON arrays
- [object_t](object_t.md) the type used to store JSON objects
## Version history
- Added in version 1.0.0.
@@ -33,6 +33,10 @@ Thereby, `Target` is the current object; that is, the patch is applied to the cu
`apply_patch` (in)
: the patch to apply
## Exception safety
Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified.
## Complexity
Linear in the lengths of `apply_patch`.
@@ -32,18 +32,18 @@ type to use.
## Notes
#### Default type
### Default type
With the default values for `NumberFloatType` (`double`), the default value for `number_float_t` is `#!cpp double`.
#### Default behavior
### Default behavior
- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in floating-point literals will
be ignored. Internally, the value will be stored as a decimal number. For instance, the C++ floating-point literal
`01.2` will be serialized to `1.2`. During deserialization, leading zeros yield an error.
- Not-a-number (NaN) values will be serialized to `null`.
#### Limits
### Limits
[RFC 8259](https://tools.ietf.org/html/rfc8259) states:
> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software
@@ -55,7 +55,7 @@ This implementation does exactly follow this approach, as it uses double precisi
smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally
and be serialized to `null`.
#### Storage
### Storage
Floating-point number values are stored directly inside a `basic_json` type.
@@ -75,6 +75,13 @@ Floating-point number values are stored directly inside a `basic_json` type.
--8<-- "examples/number_float_t.output"
```
## See also
- [number_integer_t](number_integer_t.md) the type used to store JSON integer numbers
- [number_unsigned_t](number_unsigned_t.md) the type used to store JSON unsigned integer numbers
- [is_number_float](is_number_float.md) checks whether the JSON value is a floating-point number
- [Number Handling](../../features/types/number_handling.md) - the article on number handling
## Version history
- Added in version 1.0.0.
@@ -29,18 +29,18 @@ to use.
## Notes
#### Default type
### Default type
With the default values for `NumberIntegerType` (`std::int64_t`), the default value for `number_integer_t` is
`#!cpp std::int64_t`.
#### Default behavior
### Default behavior
- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an
interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++
integer literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error.
#### Limits
### Limits
[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the range and precision of numbers.
@@ -57,7 +57,7 @@ will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [
As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is
interoperable.
#### Storage
### Storage
Integer number values are stored directly inside a `basic_json` type.
@@ -77,6 +77,13 @@ Integer number values are stored directly inside a `basic_json` type.
--8<-- "examples/number_integer_t.output"
```
## See also
- [number_unsigned_t](number_unsigned_t.md) the type used to store JSON unsigned integer numbers
- [number_float_t](number_float_t.md) the type used to store JSON floating-point numbers
- [is_number_integer](is_number_integer.md) checks whether the JSON value is a signed integer number
- [Number Handling](../../features/types/number_handling.md) - the article on number handling
## Version history
- Added in version 1.0.0.
@@ -30,18 +30,18 @@ the type to use.
## Notes
#### Default type
### Default type
With the default values for `NumberUnsignedType` (`std::uint64_t`), the default value for `number_unsigned_t` is
`#!cpp std::uint64_t`.
#### Default behavior
### Default behavior
- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an
interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++
integer literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error.
#### Limits
### Limits
[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the range and precision of numbers.
@@ -58,7 +58,7 @@ as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_
As this range is a subrange (when considered in conjunction with the `number_integer_t` type) of the exactly supported
range [0, UINT64_MAX], this class's integer type is interoperable.
#### Storage
### Storage
Integer number values are stored directly inside a `basic_json` type.
@@ -78,6 +78,13 @@ Integer number values are stored directly inside a `basic_json` type.
--8<-- "examples/number_unsigned_t.output"
```
## See also
- [number_integer_t](number_integer_t.md) the type used to store JSON integer numbers
- [number_float_t](number_float_t.md) the type used to store JSON floating-point numbers
- [is_number_unsigned](is_number_unsigned.md) checks whether the JSON value is an unsigned integer number
- [Number Handling](../../features/types/number_handling.md) - the article on number handling
## Version history
- Added in version 2.0.0.
@@ -25,6 +25,11 @@ and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise.
--8<-- "examples/object_comparator_t.output"
```
## See also
- [object_t](object_t.md) the type used to store JSON objects
- [default_object_comparator_t](default_object_comparator_t.md) the fallback comparator used when `object_t` has no `key_compare` member type
## Version history
- Added in version 3.0.0.
+14 -7
View File
@@ -33,7 +33,7 @@ To store objects in C++, a type is defined by the template parameters described
## Notes
#### Default type
### Default type
With the default values for `ObjectType` (`std::map`), `StringType` (`std::string`), and `AllocatorType`
(`std::allocator`), the default value for `object_t` is:
@@ -58,7 +58,7 @@ std::map<
See [`default_object_comparator_t`](default_object_comparator_t.md) for more information.
#### Behavior
### Behavior
The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following
behavior:
@@ -76,7 +76,7 @@ behavior:
that they will not be affected by these differences. For instance, `#!json {"b": 1, "a": 2}` and
`#!json {"a": 2, "b": 1}` will be treated as equal.
#### Limits
### Limits
[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
> An implementation may set limits on the maximum depth of nesting.
@@ -85,12 +85,12 @@ In this class, the object's limit of nesting is not explicitly constrained. Howe
introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the
[`max_size`](max_size.md) function of a JSON object.
#### Storage
### Storage
Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type
`object_t*` must be dereferenced.
#### Object key order
### Object key order
The order name/value pairs are added to the object are *not* preserved by the library. Therefore, iterating an object
may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in
@@ -98,10 +98,10 @@ alphabetical order as `std::map` with `std::less` is used by default. Please not
[RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON
objects.
#### Cross-`basic_json` conversion requirements
### Cross-`basic_json` conversion requirements
When converting an object from one `basic_json` specialization to another via the
[converting constructor](basic_json.md#overload-4), the target `object_t`'s `key_type` must be
[converting constructor](basic_json.md) (overload 4), the target `object_t`'s `key_type` must be
directly constructible from the source `basic_json`'s `string_t` type (or more generally, from the
source object's key type). If this requirement is not met, the conversion does not fail; instead,
the object is silently converted as an array of key-value pairs, which is incorrect. See
@@ -123,6 +123,13 @@ the object is silently converted as an array of key-value pairs, which is incorr
--8<-- "examples/object_t.output"
```
## See also
- [array_t](array_t.md) the type used to store JSON arrays
- [string_t](string_t.md) the type used to store JSON strings
- [object_comparator_t](object_comparator_t.md) the comparator used to order object keys
- [Object Order](../../features/object_order.md) - the article on object key ordering
## Version history
- Added in version 1.0.0.
@@ -48,6 +48,12 @@ invalidates all iterators and all references.
`#!cpp *this`
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a `#!json null`
value is converted to an empty array or object before the element is added and keeps that type if adding the element
throws.
## Exceptions
1. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than
+17 -1
View File
@@ -70,6 +70,9 @@ Strong exception safety: if an exception occurs, the original value stays intact
1. The function can throw the following exceptions:
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an array
or null; in that case, using the `[]` operator with an index makes no sense.
- Throws `#!cpp std::length_error` if `idx` equals the maximum value of `size_type`; the array is left unchanged.
(This is the one index for which growing the array to hold it cannot be expressed as a `size_type` size, the same
way an oversized [`resize`](https://en.cppreference.com/w/cpp/container/vector/resize) throws.)
2. The function can throw the following exceptions:
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an object
or null; in that case, using the `[]` operator with a key makes no sense.
@@ -133,6 +136,18 @@ Strong exception safety: if an exception occurs, the original value stays intact
while `/foo/one/one/one` creates nested objects. This is not specified by the JSON Pointer RFC; it is
this library's own, intentional disambiguation rule. See also [JSON Pointer](../../features/json_pointer.md).
!!! warning "Deprecation"
Overload (4) also accepts a [`json_pointer`](../json_pointer/index.md) whose template argument is a `basic_json`
specialization (e.g., `nlohmann::json_pointer<nlohmann::json>`) instead of a string type. This is deprecated since
version 3.11.0 and will be removed in a future major version; use `basic_json::json_pointer` (for `json`,
`nlohmann::json_pointer<std::string>`) instead.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#json-pointers) for how to update existing code.
## Examples
??? example "Example: (1) access specified array element"
@@ -257,7 +272,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
## Version history
1. Added in version 1.0.0.
1. Added in version 1.0.0. Fixed in version 3.13.0 to throw `#!cpp std::length_error` instead of emptying the array and
accessing it out of bounds when `idx` equals the maximum value of `size_type`.
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3)
in version 3.11.0.
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
@@ -17,6 +17,11 @@ Implicit type conversion between the JSON value and a compatible value. The call
copy of the JSON value, converted to `ValueType`
## Exception safety
Depends on what `json_serializer<ValueType>` `from_json()` method throws; the JSON value itself is never modified,
since `#!cpp operator ValueType()` is a `#!cpp const` member function that only calls [`get()`](get.md).
## Exceptions
Depends on what `json_serializer<ValueType>` `from_json()` method throws
@@ -56,6 +61,8 @@ Linear in the size of the JSON value.
[`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) to `0` and replace any implicit
conversions with calls to [`get`](../basic_json/get.md).
See the [migration guide](../../integration/migration_guide.md#replace-implicit-conversions) for how to update existing code.
## Examples
??? example
@@ -63,7 +70,7 @@ Linear in the size of the JSON value.
The example below shows several conversions from JSON values to other types. There are a few things to note: (1)
Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard
`std::vector<short>`, (3) A JSON object can be converted to C++ associative containers such as
`std::unordered_map<std::string, json>`.
`std::map<std::string, json>`.
```cpp
--8<-- "examples/operator__ValueType.cpp"
@@ -134,7 +134,7 @@ Linear.
## Examples
??? example
??? example "Example: (1) compare JSON values"
The example demonstrates comparing several JSON types.
@@ -148,7 +148,7 @@ Linear.
--8<-- "examples/operator__equal.output"
```
??? example
??? example "Example: (2) compare JSON values with `#!cpp nullptr`"
The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`).
@@ -60,6 +60,16 @@ Linear.
Since C++20 overload resolution will consider the _rewritten candidate_ generated from
[`operator<=>`](operator_spaceship.md).
!!! warning "Deprecation"
If [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../macros/json_use_legacy_discarded_value_comparison.md) is
defined to `1`, the library declares a member `#!cpp bool operator>=(const_reference rhs) const noexcept` in
C++20 mode to emulate the legacy comparison of discarded values. This member is deprecated since version 3.11.0,
together with the legacy comparison behavior.
See the [migration guide](../../integration/migration_guide.md#miscellaneous-functions) for how to update existing
code.
## Examples
??? example
@@ -61,6 +61,16 @@ Linear.
Since C++20 overload resolution will consider the _rewritten candidate_ generated from
[`operator<=>`](operator_spaceship.md).
!!! warning "Deprecation"
If [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../macros/json_use_legacy_discarded_value_comparison.md) is
defined to `1`, the library declares a member `#!cpp bool operator<=(const_reference rhs) const noexcept` in
C++20 mode to emulate the legacy comparison of discarded values. This member is deprecated since version 3.11.0,
together with the legacy comparison behavior.
See the [migration guide](../../integration/migration_guide.md#miscellaneous-functions) for how to update existing
code.
## Examples
??? example
+18 -15
View File
@@ -9,17 +9,9 @@ bool operator!=(const_reference lhs, const ScalarType rhs) noexcept; // (2)
template<typename ScalarType>
bool operator!=(ScalarType lhs, const const_reference rhs) noexcept; // (2)
// since C++20
class basic_json {
bool operator!=(const_reference rhs) const noexcept; // (1)
template<typename ScalarType>
bool operator!=(ScalarType rhs) const noexcept; // (2)
};
```
1. Compares two JSON values for inequality. Returns `#!cpp !(lhs == rhs)` (until C++20) or `#!cpp !(*this == rhs)` (since C++20).
1. Compares two JSON values for inequality. Returns `#!cpp !(lhs == rhs)`.
- This means the comparison is simply the logical negation of `operator==`, including for special values like `NaN` and `discarded`.
2. Compares a JSON value and a scalar or a scalar and a JSON value for inequality by converting the scalar to a JSON
@@ -52,6 +44,11 @@ Linear.
## Notes
!!! note "C++20"
Since C++20, `basic_json` declares no `operator!=`. The compiler rewrites `#!cpp a != b` as `#!cpp !(a == b)`
using [`operator==`](operator_eq.md), so the result is the same as described above.
!!! note "Comparing `NaN` and `discarded`"
Since `operator!=` is defined as `!(a == b)`, the behavior for special values follows that of `operator==`:
@@ -61,7 +58,7 @@ Linear.
## Examples
??? example
??? example "Example: (1) compare JSON values"
The example demonstrates comparing several JSON types.
@@ -75,7 +72,7 @@ Linear.
--8<-- "examples/operator__notequal.output"
```
??? example
??? example "Example: (2) compare JSON values with `#!cpp nullptr`"
The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`).
@@ -89,9 +86,15 @@ Linear.
--8<-- "examples/operator__notequal__nullptr_t.output"
```
## See also
- [operator==](operator_eq.md) comparison: equal
- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20)
## Version history
1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Changed in version 3.13.0 to remove
special-casing for `NaN` and `discarded` values; `operator!=` now consistently means `!(a == b)`.
2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Changed in version 3.13.0 to remove
special-casing for `NaN` and `discarded` values; `operator!=` now consistently means `!(a == b)`.
1. Added in version 1.0.0. Added a C++20 member function in version 3.11.0. Changed in version 3.13.0 to remove
special-casing for `NaN` and `discarded` values; `operator!=` now consistently means `!(a == b)`. Removed the C++20
member function in version 3.13.0; since C++20, the compiler rewrites `a != b` using `operator==`.
2. Added in version 1.0.0. Changed in version 3.13.0 to remove special-casing for `NaN` and `discarded` values;
`operator!=` now consistently means `!(a == b)`. Since C++20, the compiler rewrites `a != b` using `operator==`.
@@ -47,6 +47,11 @@ Constant.
--8<-- "examples/operator__value_t.output"
```
## See also
- [type](type.md) named member function equivalent to this implicit conversion operator
- [value_t](value_t.md) the enumeration of JSON types
## Version history
- Added in version 1.0.0.
+19 -10
View File
@@ -88,7 +88,12 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
## Exceptions
- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token, or
empty input like a null `FILE*` or `char*` pointer.
empty input like a null `FILE*` or `char*` pointer, or an `std::istream` without a stream buffer
(`#!cpp i.rdbuf() == nullptr`, for instance `#!cpp std::istream(nullptr)`).
- If reading from an `std::istream` reaches the end of the input and `eofbit` is part of the stream's
[`exceptions()`](https://en.cppreference.com/w/cpp/io/basic_ios/exceptions) mask, the `std::ios_base::failure`
thrown by the stream itself propagates instead of a `parse_error`, the same as it would for the standard library's
own extraction operators.
## Complexity
@@ -109,7 +114,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
## Examples
??? example "Parsing from a character array"
??? example "Example: (1) parse from a character array"
The example below demonstrates the `parse()` function reading from an array.
@@ -123,7 +128,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/parse__array__parser_callback_t.output"
```
??? example "Parsing from a string"
??? example "Example: (1) parse from a string"
The example below demonstrates the `parse()` function with and without callback function.
@@ -137,7 +142,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/parse__string__parser_callback_t.output"
```
??? example "Parsing from an input stream"
??? example "Example: (1) parse from an input stream"
The example below demonstrates the `parse()` function with and without callback function.
@@ -151,7 +156,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/parse__istream__parser_callback_t.output"
```
??? example "Parsing from a contiguous container"
??? example "Example: (1) parse from a contiguous container"
The example below demonstrates the `parse()` function reading from a contiguous container.
@@ -165,7 +170,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/parse__contiguouscontainer__parser_callback_t.output"
```
??? example "Parsing from a non-null-terminated string"
??? example "Example: (2) parse from a non-null-terminated string"
The example below demonstrates the `parse()` function reading from a string that is not null-terminated.
@@ -179,7 +184,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/parse__pointers.output"
```
??? example "Parsing from an iterator pair"
??? example "Example: (2) parse from an iterator pair"
The example below demonstrates the `parse()` function reading from an iterator pair.
@@ -193,7 +198,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/parse__iterator_pair.output"
```
??? example "Effect of `allow_exceptions` parameter"
??? example "Example: effect of `allow_exceptions` parameter"
The example below demonstrates the effect of the `allow_exceptions` parameter in the `parse()` function.
@@ -207,7 +212,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/parse__allow_exceptions.output"
```
??? example "Effect of `ignore_comments` parameter"
??? example "Example: effect of `ignore_comments` parameter"
The example below demonstrates the effect of the `ignore_comments` parameter in the `parse()` function.
@@ -221,7 +226,7 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
--8<-- "examples/comments.output"
```
??? example "Effect of `ignore_trailing_commas` parameter"
??? example "Example: effect of `ignore_trailing_commas` parameter"
The example below demonstrates the effect of the `ignore_trailing_commas` parameter in the `parse()` function.
@@ -254,6 +259,8 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0.
- `JSON_STRICT_NUL_HANDLING` added in version 3.13.0 to optionally reject a NUL byte in the input instead of treating
it as end of input; planned to become the default in version 4.0.0.
- Extended empty-input detection to also cover an `std::istream` without a stream buffer, and fixed a crash
(`std::terminate`) when parsing from an `std::istream` with `eofbit` in its exception mask, in version 3.13.0.
!!! warning "Deprecation"
@@ -263,3 +270,5 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#parsing) for how to update existing code.
@@ -24,6 +24,21 @@ The parser callback distinguishes the following events:
![Example when certain parse events are triggered](../../images/callback_events.png)
??? example
The following code parses a small JSON text with a parser callback that reports every event together with its
depth and keeps every value (by always returning `#!cpp true`).
```cpp
--8<-- "examples/parse_event_t.cpp"
```
Output:
```json
--8<-- "examples/parse_event_t.output"
```
## See also
- [parser_callback_t](parser_callback_t.md) callback function type for the parser
@@ -60,7 +60,7 @@ the latter case, it is skipped completely, or replaced by `null` if it is the to
## Examples
??? example
??? example "Example: skip an object key while parsing"
The example below demonstrates the `parse()` function with
and without callback function.
@@ -75,7 +75,7 @@ the latter case, it is skipped completely, or replaced by `null` if it is the to
--8<-- "examples/parse__string__parser_callback_t.output"
```
??? example
??? example "Example: how discarded values are removed"
The example below shows where discarded values are removed. The array and the number are discarded in different
ways, but in each case the parse result contains neither the value nor its key.
@@ -100,3 +100,6 @@ the latter case, it is skipped completely, or replaced by `null` if it is the to
- Added in version 1.0.0.
- Fixed in version 3.13.0 to also remove discarded values from a parent object; before, discarding an array or a value
stored under an object key left a discarded member behind, which made the parse result serialize to invalid JSON.
- Fixed in version 3.13.0 so that discarding an array or object at its start event also hides its content from the
callback, as documented above; before, the callback was still called for the content, and the key of every member of
a discarded object was kept in memory until the parse ended.
+31 -2
View File
@@ -26,10 +26,24 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of
an array of objects.
- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g.,
mandatory attributes are missing); example: `"operation add must have member path"`.
mandatory attributes are missing); example: `"operation 'add' must have member 'path'"`.
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range.
- Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in a "path" or
"from" member begins with '0'; example: `"array index '01' must not begin with '0'"`.
- Throws [`parse_error.107`](../../home/exceptions.md#jsonexceptionparse_error107) if a "path" or "from" member is not
empty and does not begin with a slash (`/`); example: `"JSON pointer must be empty or begin with '/' - was: 'a'"`.
- Throws [`parse_error.108`](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in a "path" or
"from" member is not followed by `0` or `1`; example: `"escape character '~' must be followed with '0' or '1'"`.
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a "path" or
"from" member is not a number; example: `"array index 'foo' is not a number"`.
- Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index `-` is used
where an existing element is required (the "path" of "replace", the "from" of "move" and "copy"); example:
`"array index '-' (3) is out of range"`.
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch
could not be resolved successfully in the current JSON value; example: `"key baz not found"`.
- Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a reference token of a JSON
pointer inside the patch cannot be resolved, e.g., `-` in a "remove" operation or `1a` for an array; example:
`"unresolved reference token '-'"`.
- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent
("add", "remove", "move")
- Throws [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) if an "add" operation's target
@@ -53,7 +67,7 @@ is thrown. In any case, the original value is not changed: the patch is applied
## Examples
??? example
??? example "Example: apply a JSON patch"
The following code shows how a JSON patch is applied to a value.
@@ -67,6 +81,21 @@ is thrown. In any case, the original value is not changed: the patch is applied
--8<-- "examples/patch.output"
```
??? example "Example: out_of_range.414 exception"
The following code shows how a "move" operation whose "from" location is a proper prefix of its "path" location is
rejected, and how the original document is left unchanged because the patch is applied to a copy.
```cpp
--8<-- "examples/patch__exception.cpp"
```
Output:
```json
--8<-- "examples/patch__exception.output"
```
## See also
- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
@@ -22,10 +22,24 @@ No guarantees, value may be corrupted by an unsuccessful patch operation.
- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of
an array of objects.
- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g.,
mandatory attributes are missing); example: `"operation add must have member path"`.
mandatory attributes are missing); example: `"operation 'add' must have member 'path'"`.
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range.
- Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in a "path" or
"from" member begins with '0'; example: `"array index '01' must not begin with '0'"`.
- Throws [`parse_error.107`](../../home/exceptions.md#jsonexceptionparse_error107) if a "path" or "from" member is not
empty and does not begin with a slash (`/`); example: `"JSON pointer must be empty or begin with '/' - was: 'a'"`.
- Throws [`parse_error.108`](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in a "path" or
"from" member is not followed by `0` or `1`; example: `"escape character '~' must be followed with '0' or '1'"`.
- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a "path" or
"from" member is not a number; example: `"array index 'foo' is not a number"`.
- Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index `-` is used
where an existing element is required (the "path" of "replace", the "from" of "move" and "copy"); example:
`"array index '-' (3) is out of range"`.
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch
could not be resolved successfully in the current JSON value; example: `"key baz not found"`.
- Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a reference token of a JSON
pointer inside the patch cannot be resolved, e.g., `-` in a "remove" operation or `1a` for an array; example:
`"unresolved reference token '-'"`.
- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent
("add", "remove", "move")
- Throws [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) if an "add" operation's target
@@ -50,7 +64,7 @@ function throws an exception.
## Examples
??? example
??? example "Example: apply a JSON patch in place"
The following code shows how a JSON patch is applied to a value.
@@ -64,6 +78,22 @@ function throws an exception.
--8<-- "examples/patch_inplace.output"
```
??? example "Example: out_of_range.403 exception with a partially applied patch"
The following code shows a patch whose first operation succeeds and whose second operation fails. Because
`patch_inplace` applies each operation directly to the value, the first operation's effect is still visible after
the exception is caught, unlike [`patch`](patch.md).
```cpp
--8<-- "examples/patch_inplace__exception.cpp"
```
Output:
```json
--8<-- "examples/patch_inplace__exception.output"
```
## See also
- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
@@ -44,6 +44,12 @@ invalidates all iterators and all references.
`init` (in)
: an initializer list
## Exception safety
Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a `#!json null`
value is converted to an empty array or object before the element is added and keeps that type if adding the element
throws.
## Exceptions
1. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than
@@ -37,6 +37,13 @@ Constant.
--8<-- "examples/rbegin.output"
```
## See also
- [rend](rend.md) returns a reverse iterator to one before the first element
- [crbegin](crbegin.md) returns a const reverse iterator to the last element
- [begin](begin.md) returns an iterator to the first element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
+7
View File
@@ -38,6 +38,13 @@ Constant.
--8<-- "examples/rend.output"
```
## See also
- [rbegin](rbegin.md) returns a reverse iterator to the last element
- [crend](crend.md) returns a const reverse iterator to one before the first element
- [end](end.md) returns an iterator to one past the last element
- [Iterators](../../features/iterators.md) - the article on iterators
## Version history
- Added in version 1.0.0.
@@ -147,3 +147,5 @@ A UTF-8 byte order mark is silently ignored.
Overload (2) replaces calls to `sax_parse` 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
`#!cpp sax_parse({ptr, ptr+len});` with `#!cpp sax_parse(ptr, ptr+len);`.
See the [migration guide](../../integration/migration_guide.md#parsing) for how to update existing code.
+5
View File
@@ -51,6 +51,11 @@ JSON value which is `1` in the case of a string.
--8<-- "examples/size.output"
```
## See also
- [empty](empty.md) checks whether the JSON value has no elements
- [max_size](max_size.md) returns the maximum possible number of elements
## Version history
- Added in version 1.0.0.
@@ -28,6 +28,10 @@ type of the JSON value is taken into account to have different hash values for `
Note the output is platform-dependent.
## See also
- [operator==](operator_eq.md) compares two JSON values for equality, consistent with equal hash values
## Version history
- Added in version 1.0.0.
+12 -6
View File
@@ -30,16 +30,16 @@ JSON class into byte-sized characters during deserialization.
## Notes
#### Default type
### Default type
With the default values for `StringType` (`std::string`), the default value for `string_t` is `#!cpp std::string`.
#### Encoding
### Encoding
Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return
the number of bytes in the string rather than the number of characters or glyphs.
#### String comparison
### String comparison
[RFC 8259](https://tools.ietf.org/html/rfc8259) states:
> Software implementations are typically required to test names of object members for equality. Implementations that
@@ -50,15 +50,15 @@ the number of bytes in the string rather than the number of characters or glyphs
This implementation is interoperable as it does compare strings code unit by code unit.
#### Storage
### Storage
String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type
`string_t*` must be dereferenced.
#### Cross-`basic_json` conversion requirements
### Cross-`basic_json` conversion requirements
When converting a string value from one `basic_json` specialization to another via the
[converting constructor](basic_json.md#overload-4), the target `string_t` must be directly
[converting constructor](basic_json.md) (overload 4), the target `string_t` must be directly
constructible from the source `basic_json`'s `string_t` type. If this requirement is not met, the
conversion does not fail; instead, the string is silently converted as an array of character codes,
which is incorrect. See [issue #3425](https://github.com/nlohmann/json/issues/3425) for details
@@ -80,6 +80,12 @@ and an example.
--8<-- "examples/string_t.output"
```
## See also
- [object_t](object_t.md) the type used to store JSON objects (and their keys, which are also `string_t`)
- [binary_t](binary_t.md) the type used to store binary values
- [get_ptr](get_ptr.md) returns a pointer to the stored string value
## Version history
- Added in version 1.0.0.
+27 -9
View File
@@ -6,7 +6,9 @@ void swap(reference other) noexcept (
std::is_nothrow_move_constructible<value_t>::value &&
std::is_nothrow_move_assignable<value_t>::value &&
std::is_nothrow_move_constructible<json_value>::value &&
std::is_nothrow_move_assignable<json_value>::value
std::is_nothrow_move_assignable<json_value>::value &&
std::is_nothrow_move_constructible<json_base_class_t>::value &&
std::is_nothrow_move_assignable<json_base_class_t>::value
);
// (2)
@@ -14,7 +16,9 @@ friend void swap(reference left, reference right) noexcept (
std::is_nothrow_move_constructible<value_t>::value &&
std::is_nothrow_move_assignable<value_t>::value &&
std::is_nothrow_move_constructible<json_value>::value &&
std::is_nothrow_move_assignable<json_value>::value
std::is_nothrow_move_assignable<json_value>::value &&
std::is_nothrow_move_constructible<json_base_class_t>::value &&
std::is_nothrow_move_assignable<json_base_class_t>::value
);
// (3)
@@ -37,11 +41,15 @@ void swap(typename binary_t::container_type& other);
individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. If macro
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) is defined to `#!cpp 1`, the
[`start_pos()`](start_pos.md)/[`end_pos()`](end_pos.md) diagnostic positions are exchanged along with the value.
The [`json_base_class_t`](json_base_class_t.md) subobject is exchanged along with the value as well, the same way it
is copied or moved by the copy/move constructors and assignment operators.
2. Exchanges the contents of the JSON value from `left` with those of `right`. Does not invoke any move, copy, or swap
operations on individual elements. All iterators and references remain valid. The past-the-end iterator is
invalidated. Implemented as a friend function callable via ADL. If macro
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) is defined to `#!cpp 1`, the
[`start_pos()`](start_pos.md)/[`end_pos()`](end_pos.md) diagnostic positions are exchanged along with the value.
The [`json_base_class_t`](json_base_class_t.md) subobject is exchanged along with the value as well, the same way it
is copied or moved by the copy/move constructors and assignment operators.
3. Exchanges the contents of a JSON array with those of `other`. Does not invoke any move, copy, or swap operations on
individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.
4. Exchanges the contents of a JSON object with those of `other`. Does not invoke any move, copy, or swap operations on
@@ -65,6 +73,16 @@ void swap(typename binary_t::container_type& other);
`right` (in, out)
: value to exchange the contents with
## Exception safety
1. No-throw guarantee: this function never throws exceptions.
2. No-throw guarantee: this function never throws exceptions.
3. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
4. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
5. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
6. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
7. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
## Exceptions
1. No-throw guarantee: this function never throws exceptions.
@@ -86,7 +104,7 @@ Constant.
## Examples
??? example "Example: Swap JSON value (1, 2)"
??? example "Example: (1, 2) swap JSON values"
The example below shows how JSON values can be swapped with `swap()`.
@@ -100,7 +118,7 @@ Constant.
--8<-- "examples/swap__reference.output"
```
??? example "Example: Swap array (3)"
??? example "Example: (3) swap array"
The example below shows how arrays can be swapped with `swap()`.
@@ -114,7 +132,7 @@ Constant.
--8<-- "examples/swap__array_t.output"
```
??? example "Example: Swap object (4)"
??? example "Example: (4) swap object"
The example below shows how objects can be swapped with `swap()`.
@@ -128,7 +146,7 @@ Constant.
--8<-- "examples/swap__object_t.output"
```
??? example "Example: Swap string (5)"
??? example "Example: (5) swap string"
The example below shows how strings can be swapped with `swap()`.
@@ -142,7 +160,7 @@ Constant.
--8<-- "examples/swap__string_t.output"
```
??? example "Example: Swap binary (6)"
??? example "Example: (6) swap binary"
The example below shows how binary values can be swapped with `swap()`.
@@ -164,8 +182,8 @@ Constant.
## Version history
1. Since version 1.0.0.
2. Since version 1.0.0.
1. Since version 1.0.0. Exchanges the `json_base_class_t` subobject along with the value since version 3.13.0.
2. Since version 1.0.0. Exchanges the `json_base_class_t` subobject along with the value since version 3.13.0.
3. Since version 1.0.0.
4. Since version 1.0.0.
5. Since version 1.0.0.
+17 -2
View File
@@ -55,7 +55,7 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
## Exceptions
- Throws [`other_error.502`](../../home/exceptions.md#jsonexceptionother_error502) if `use_type` is true and `use_size`
is false.
is false, and `j` contains a non-empty array, object, or binary value.
## Complexity
@@ -63,7 +63,7 @@ Linear in the size of the JSON value `j`.
## Examples
??? example
??? example "Example: serialize a JSON value to BJData"
The example shows the serialization of a JSON value to a byte vector in BJData format.
@@ -77,6 +77,21 @@ Linear in the size of the JSON value `j`.
--8<-- "examples/to_bjdata.output"
```
??? example "Example: other_error.502 exception"
The example shows how requesting type annotations (`use_type`) without size annotations (`use_size`) throws an
exception, because type-optimized containers can only be read back with a preceding size.
```cpp
--8<-- "examples/to_bjdata__exception.cpp"
```
Output:
```json
--8<-- "examples/to_bjdata__exception.output"
```
## See also
- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format
+16 -1
View File
@@ -48,7 +48,7 @@ Linear in the size of the JSON value `j`.
## Examples
??? example
??? example "Example: serialize a JSON value to BON8"
The example shows the serialization of a JSON value to a byte vector in BON8 format.
@@ -62,6 +62,21 @@ Linear in the size of the JSON value `j`.
--8<-- "examples/to_bon8.output"
```
??? example "Example: type_error.316 exception"
The example shows how serializing a string that is not valid UTF-8 throws an exception, because BON8 stores strings
as UTF-8.
```cpp
--8<-- "examples/to_bon8__exception.cpp"
```
Output:
```json
--8<-- "examples/to_bon8__exception.output"
```
## See also
- [from_bon8](from_bon8.md) create a JSON value from an input in BON8 format
+21 -1
View File
@@ -43,6 +43,9 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
- Throws [`out_of_range.412`](../../home/exceptions.md#jsonexceptionout_of_range412) if the length of a document, array,
string, or binary value exceeds the range of the 32-bit BSON length field; example:
`"BSON length 2147483661 exceeds maximum of 2147483647"`
- Throws [`out_of_range.415`](../../home/exceptions.md#jsonexceptionout_of_range415) if the subtype of a binary value
exceeds 255, the maximum of the BSON binary subtype; example:
`"subtype 70000 is too large for the BSON binary subtype (max 255)"`
## Complexity
@@ -51,7 +54,7 @@ pass before anything is written.
## Examples
??? example
??? example "Example: serialize a JSON value to BSON"
The example shows the serialization of a JSON value to a byte vector in BSON format.
@@ -65,6 +68,21 @@ pass before anything is written.
--8<-- "examples/to_bson.output"
```
??? example "Example: out_of_range.409 exception"
The example shows how serializing a JSON object whose key contains a null byte (U+0000) throws an exception, because
BSON keys are null-terminated C strings and cannot contain U+0000 themselves.
```cpp
--8<-- "examples/to_bson__exception.cpp"
```
Output:
```json
--8<-- "examples/to_bson__exception.output"
```
## See also
- [from_bson](from_bson.md) create a JSON value from an input in BSON format
@@ -77,4 +95,6 @@ pass before anything is written.
## Version history
- Added in version 3.4.0.
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
- Linear in the size of `j`, and no longer limited by the call stack for deeply nested values, since version 3.13.0.
- `out_of_range.415` is now detected before anything is written, like the other exceptions above, since version 3.13.0.
+19 -1
View File
@@ -49,7 +49,7 @@ Linear in the size of the JSON value `j`.
## Examples
??? example
??? example "Example: serialize a JSON value to MessagePack"
The example shows the serialization of a JSON value to a byte vector in MessagePack format.
@@ -63,6 +63,21 @@ Linear in the size of the JSON value `j`.
--8<-- "examples/to_msgpack.output"
```
??? example "Example: out_of_range.415 exception"
The example shows how serializing a binary value whose subtype exceeds 255 throws an exception, because the
MessagePack ext type stores the subtype in a single byte.
```cpp
--8<-- "examples/to_msgpack__exception.cpp"
```
Output:
```json
--8<-- "examples/to_msgpack__exception.output"
```
## See also
- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format
@@ -76,3 +91,6 @@ Linear in the size of the JSON value `j`.
- Added in version 2.0.9.
- Throws `out_of_range.412` and `out_of_range.415` since version 3.13.0.
- Fixed in version 3.13.0 to serialize `number_integer_t`/`number_unsigned_t` pairs of different width correctly;
before, integers could be serialized with the wrong value if `number_integer_t` was narrower than
`number_unsigned_t`.
+2 -1
View File
@@ -10,7 +10,8 @@ This function implements a user-defined to_string for JSON objects.
## Template parameters
`BasicJsonType`
: a specialization of [`basic_json`](index.md)
: a specialization of [`basic_json`](index.md) whose [`string_t`](string_t.md) is convertible to `#!cpp std::string`;
for other string types, use [`dump`](dump.md), which returns a `string_t`
## Return value
+17 -2
View File
@@ -48,7 +48,7 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
## Exceptions
- Throws [`other_error.502`](../../home/exceptions.md#jsonexceptionother_error502) if `use_type` is true and `use_size`
is false.
is false, and `j` contains a non-empty array, object, or binary value.
## Complexity
@@ -56,7 +56,7 @@ Linear in the size of the JSON value `j`.
## Examples
??? example
??? example "Example: serialize a JSON value to UBJSON"
The example shows the serialization of a JSON value to a byte vector in UBJSON format.
@@ -70,6 +70,21 @@ Linear in the size of the JSON value `j`.
--8<-- "examples/to_ubjson.output"
```
??? example "Example: other_error.502 exception"
The example shows how requesting type annotations (`use_type`) without size annotations (`use_size`) throws an
exception, because type-optimized containers can only be read back with a preceding size.
```cpp
--8<-- "examples/to_ubjson__exception.cpp"
```
Output:
```json
--8<-- "examples/to_ubjson__exception.output"
```
## See also
- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format
+6
View File
@@ -47,6 +47,12 @@ Constant.
--8<-- "examples/type.output"
```
## See also
- [operator value_t](operator_value_t.md) implicit conversion operator equivalent to this named member function
- [type_name](type_name.md) returns the type as a string, for use in error messages
- [value_t](value_t.md) the enumeration of JSON types
## Version history
- Added in version 1.0.0.
@@ -52,6 +52,11 @@ Constant.
--8<-- "examples/type_name.output"
```
## See also
- [type](type.md) returns the type of the JSON value
- [value_t](value_t.md) the enumeration of JSON types
## Version history
- Added in version 1.0.0.
@@ -27,8 +27,17 @@ The function can throw the following exceptions:
- Throws [`type_error.315`](../../home/exceptions.md#jsonexceptiontype_error315) if object values are not primitive
- Throws [`type_error.313`](../../home/exceptions.md#jsonexceptiontype_error313) if a key (JSON pointer) leads to a
conflicting nesting; example: `"invalid value to unflatten"`
- Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in a key begins
with '0'; example: `"array index '01' must not begin with '0'"`
- Throws [`parse_error.107`](../../home/exceptions.md#jsonexceptionparse_error107) if a key is not empty and does not
begin with a slash (`/`); example: `"JSON pointer must be empty or begin with '/' - was: 'a'"`
- Throws [`parse_error.108`](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in a key is not
followed by `0` or `1`; example: `"escape character '~' must be followed with '0' or '1'"`
- 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"`
- 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:
`"unresolved reference token 'x'"`
## Complexity
+3 -3
View File
@@ -61,7 +61,7 @@ Basic guarantee: if an exception is thrown during the operation, the JSON value
## Examples
??? example
??? example "Example: (1) update with another object"
The example shows how `update()` is used.
@@ -75,7 +75,7 @@ Basic guarantee: if an exception is thrown during the operation, the JSON value
--8<-- "examples/update.output"
```
??? example
??? example "Example: (2) update with an iterator range"
The example shows how `update()` is used.
@@ -89,7 +89,7 @@ Basic guarantee: if an exception is thrown during the operation, the JSON value
--8<-- "examples/update__range.output"
```
??? example
??? example "Example: (1) merge user settings into default settings"
One common use case for this function is the handling of user settings. Assume your application can be configured in
some aspects:
+38 -1
View File
@@ -52,6 +52,14 @@ This is equivalent to Python's `dict.get(key, default)`.
- Unlike [`operator[]`](operator[].md), this function does not implicitly add an element to the position defined by
`key`/`ptr` key. This function is furthermore also applicable to const objects.
!!! note "Integer keys"
Calling this function with an integer `key` argument (for example, `#!cpp value(0, 1)`) does not compile in
C++11, where `object_comparator_t` is not transparent: such an argument would otherwise implicitly convert to a
null `#!cpp const char*` and, from there, cause undefined behavior when constructing a `#!cpp std::string` for the
object key. To access an array element with a default value, use [`at`](at.md) together with a `#!cpp try`/`#!cpp
catch` block, or compare against [`size`](size.md) instead.
## Template parameters
`KeyType`
@@ -133,6 +141,18 @@ changes to any JSON value.
--8<-- "examples/value__return_type.output"
```
!!! warning "Deprecation"
Overload (3) also accepts a [`json_pointer`](../json_pointer/index.md) whose template argument is a `basic_json`
specialization (e.g., `nlohmann::json_pointer<nlohmann::json>`) instead of a string type. This is deprecated since
version 3.11.0 and will be removed in a future major version; use `basic_json::json_pointer` (for `json`,
`nlohmann::json_pointer<std::string>`) instead.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.
See the [migration guide](../../integration/migration_guide.md#json-pointers) for how to update existing code.
## Examples
??? example "Example: (1) access specified object element with default value"
@@ -177,6 +197,21 @@ changes to any JSON value.
--8<-- "examples/value__json_ptr.output"
```
??? example "Example: (1) type_error.302 and type_error.306 exceptions"
The example below shows how `value()` throws `type_error.302` when the default value's type does not match the type
of the stored value, and `type_error.306` when `value()` is called on a JSON value that is not an object.
```cpp
--8<-- "examples/value__exception.cpp"
```
Output:
```json
--8<-- "examples/value__exception.output"
```
## See also
- see [`at`](at.md) for access by reference with range checking
@@ -184,7 +219,9 @@ changes to any JSON value.
## Version history
1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version 3.11.0.
1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version
3.11.0. Deleted overload for integral key types added in version 3.13.0 to reject such calls at compile time
instead of causing undefined behavior at runtime.
2. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2.
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
@@ -38,6 +38,16 @@ functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_
`discarded` is unordered.
```mermaid
flowchart LR
A[null] --> B[boolean]
B --> C["number_integer / number_unsigned / number_float"]
C --> D[object]
D --> E[array]
E --> F[string]
F --> G[binary]
```
!!! note "Types of numbers"
There are three enumerators for numbers (`number_integer`, `number_unsigned`, and `number_float`) to distinguish
@@ -74,6 +84,14 @@ functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_
--8<-- "examples/type.output"
```
## See also
- [type](type.md) return the type of the JSON value
- [type_name](type_name.md) return the type as string
- [operator value_t](operator_value_t.md) return the type of the JSON value
- [is_primitive](is_primitive.md) return whether the type is primitive
- [is_structured](is_structured.md) return whether the type is structured
## Version history
- Added in version 1.0.0.
@@ -16,6 +16,11 @@ Linear.
<!-- NOLINT Examples -->
## See also
- [basic_json](basic_json.md) constructs a JSON value
- [clear](clear.md) clears the content of a JSON value without destroying it
## Version history
- Added in version 1.0.0.
@@ -41,6 +41,14 @@ byte_container_with_subtype(container_type&& container, subtype_type subtype);
--8<-- "examples/byte_container_with_subtype__byte_container_with_subtype.output"
```
## See also
- [set_subtype](set_subtype.md) sets the binary subtype
- [subtype](subtype.md) return the binary subtype
- [has_subtype](has_subtype.md) return whether the value has a subtype
- [binary](../basic_json/binary.md) create a binary JSON value
- [Binary Values](../../features/binary_values.md) - the article on binary values
## Version history
Since version 3.8.0.
@@ -31,6 +31,12 @@ Constant.
--8<-- "examples/byte_container_with_subtype__clear_subtype.output"
```
## See also
- [set_subtype](set_subtype.md) sets the binary subtype
- [has_subtype](has_subtype.md) return whether the value has a subtype
- [subtype](subtype.md) return the binary subtype
## Version history
Since version 3.8.0.

Some files were not shown because too many files have changed in this diff Show More